比如我有一个A.func1()是异步的,它能返回一个对象x1,我还有一个B.func2()也是异步的,需要根据x1来执行,然后B.func2返回一个最终值值t,根据这个最终值t就进行一些提示性显示。请问这个要怎么写呢?
我自己写的代码是这样的
A.func1().
then(function(x1) {
B.func2(x1).
then(function(t) {
//do something
})
})
但是感觉这样用不用then就一个效果啦……还是变回金字塔了
针对评论里的补充的“promise连续调用过程中保存状态”,我想详细说几种策略
上策:去状态化
也就是调整你的逻辑,让A.func1,B.func2,和后面那个匿名函数(就叫func3吧)的调用过程不含状态,也就是让func3只依赖func2的输出,不依赖func1的输出;又或着让func2不依赖func1,用类似
Promise.all
来同时拿到func1和func2的结果丢给func3中策:“全局”变量维护状态
优点:state可扩展state.x2 .x3 ...
问题:很长的调用链带复杂状态的话,很容易污染出bug,代码可维护性下降严重
bluebird
的bind方法可以绑定thisArg,可以用来保留状态,原理是一样的中策:临时额外传递
优点:不带状态,如果调用链很长,这个额外状态被控制在两步之间,保持了较好的可维护性,不易出bug
缺点:如果长调用链的每步都有状态,会变得无比啰嗦
当然这里的内层then也可以自己封装一下优化掉
下策:闭包维护状态
其实就是题主原来的写法,我觉得主要的问题就是题主说的又降级回到了原本的“callback hell”或者说回调金字塔的难堪之中了
优点是……it works
直接在
then
里面返回一个Promise
的对象,如下:针对你评论中说的问题,如果不使用第三方的
Promise
库的话,可以像下面这样使用:使用第三方的
Promise
库可以简化这个过程。promise会返回promise对象,这样才使得它可以使用优雅的链式调用。
then里面的函数的返回值如果是一个直接量,则会作为下一个链式调用的then的参数
如果返回值具有promise的接口,则返回该promise的resolve的结果
用q做个例子