关于Promise

自从Saleforce进入Lightning时代,Promise这个在前端领域耳熟能详的名词,如当年鸦片战争的坚船利炮一般,强行闯入了Salesforce开发者的世界。

也不想谈太多的技术细节,因为Promise作为ES6的新特性,汉语的,英语的,日语的资料也是林林总总的非常详细。比如阮一峰老师的《ECMAScript 6 入门》中的此章节

其实Promise理解起来也很简单,就是按字面意思,我许诺,这事我答应你了去办。
事儿我解决了,就是resolve,没办成,就是reject。事儿办成以后咱看看下一步怎么办,就是then。如果中间出岔子了,后面的不管了,直接去找谁谁谁,就是catch。不管事儿办没办成,最后告诉我一声,就是finally。

Promise的出现可以说是为了解决Callback Hell,回调地狱。甚至还有一个网站来介绍回调地狱是什么。http://callbackhell.com/
在前端开发的上古时代,回调地狱是非常常见。在代码缩略图上
能明显的看到代码的形状是>型。
顾名思义,回调,就是我找你办事,我托你办事的时候同时也嘱咐你这件事儿办完了做什么。就是我把你处理完成时要调用的方法先传给你。
一般回调地狱发生的重灾区是多步骤的AJAX。因为AJAX调用是异步的。比如,先发AJAX请求获取一个token,然后发AJAX请求获取一个user的Id,然后再发一个AJAX请求去获得这个user的数据等等。每一步的下一步要在发出AJAX请求之前就作为回调设好。强行的将一堆异步的处理变成严格的按照先后顺序执行。

那么Promise的意义就在于,把>型的代码嵌套变成了流线型的new Promise(getToken()).then(value => getUser(value);).then(value => getRecord(value)).catch(e => console.error(e)); 在感官上更贴合“
将一堆异步的处理变成严格的按照先后顺序执行。 ”的目标。

如果说,Promise只是从>型变成了|型或者—型,好处还不够多。更重要的一点,与回调地狱写法相比,Promise提供了很好的异常处理机制。只要then链中任何一环抛出异常,都会直奔catch集中处理。

但是Promise也非完美,在极复杂情况下,比如根据上一步的返回值,要执行完全不同的业务流程,promise链就会略显无力。与此同时整条Promise链也会变的及其冗长,优点损失殆尽。还有异常处理的一些坑等有时间在讲。

所以在代码结构设计与业务流程上应尽量规避极其复杂与冗长的回调链。毕竟代码还是需要人来阅读。

Salesforce开发者也应该多去了解前端技术,看看这个世界已经发展到了什么样子,而不是固步自封在SFDC的小圈子里。

关于在Component中向Lightning Button传值的方法

某日,
打水途中看到某位同学眉头紧锁双手合十做沉思状,于是乎忍不住凑了过去。
哦。。。原来在写Lightning Component。隐隐约约看到密密麻麻的controller.js代码感觉不妙。
“咳。”为了避免吓到他,我轻咳了一下表示进场。
只见他先是略微抬起头,之后彻底滑落到了椅子上。
“唉,事情是这样的,” 他用沙哑的嗓音说道,“最开始他们要我做一个button,点了之后去后台更新一条数据,将其字段A__c更新为a。”
他把自己从椅子上重新支了起来,指着屏幕说,“这个很简单,我放了一个attribute来存需要更新的数据的id,然后在lightning button的onClick属性指定controller的方法,在controller的方法中cmp.get那个attribute的值,之后传给apex去更新这条数据。”
我微微点头表示赞同。“没毛病。然后呢?”

“然后,他们又说,要再加一个button,点这个button之后,要给这条数据的字段A__c更新为b。OK,我在cmp中加了又一个button,然后在controller里又为了新button新建了一个方法,与之前的方法不同的是,更新的值为空。”
“也不是不可以呀。“
“对,”接下来他双眼空洞的目视前方。“然后他们又让我加三个button,点了之后分别赋值b,c,d。这时候我意识到情况不对,打算在button的conlick事件把值传给controller中的方法,这样就不用每加一个button就新加一个方法了。结果……我发现……lightning button的onclick根本不能设参数,controller的方法参数也是固定的。我没办法了……”

“我明白你的意思了”。我按住了他的肩膀。

在常规前端开发中,在button的click事件中绑定的js函数传递不同的值是常见做法。如果点击button之后,处理相同,仅是需要处理的参数不同的情况应该对代码进行合理的复用。如下例。

let foo1 = function(param1) {
console.log(param1);
}
<div>
    <input type="button" name="Button" onClick="foo1('a')"/>
</div>

但是lightning button(官方文档)的onclick事件,并没有提供直接传递参数的方式。所以我们只能走曲线救国的路线。
其实很简单。
首先,在官方文档里提到,

You can retrieve the button that’s clicked by using event.getSource(). For example, to retrieve the label on the button, use event.getSource().get("v.label").

说明我们可以在controller的方法中拿到event的触发者——被点击的button,然后获得此button上的属性——比如Label。

那么就好办了,首先我们在lightning button上光明正大的设置value属性

<lightning:button label="button1" title="create" onclick="{!c.updateRecord}" value="a"/>

然后在controller的方法中,去get这个button的value属性,接下来正常执行业务逻辑就可以了。

({   
    updateRecord : function (component, event, helper) {
        let targetValue = event.getSource().get("v.value");
        // YOUR STATEMENT HERE ......
    }
})

好了,水凉了,还得重新接一杯。