如何在.then()链中访问先前的承诺结果?
我已经将我的代码重组为承诺,并构建了一个美妙的长平诺言链 ,由多个.then()
回调组成。 最后,我想返回一些复合值,并需要访问多个中间承诺结果 。 但是,从序列中间的分辨率值不在最后一次回调的范围内,我如何访问它们?
function getExample() {
return promiseA(…).then(function(resultA) {
// Some processing
return promiseB(…);
}).then(function(resultB) {
// More processing
return // How do I gain access to resultA here?
});
}
打破这个链条
当你需要访问链条中的中间值时,你应该将链条拆分成你需要的单件。 而不是附加一个回调,并以某种方式多次尝试使用其参数,将多个回调附加到相同的承诺 - 无论您需要结果值。 不要忘记,一个承诺只代表(代理)未来的价值! 接下来从线性链中的另一个承诺中获取一个承诺,使用库所提供的承诺组合器来构建结果值。
这将导致一个非常简单的控制流程,清晰的功能组成,因此易于模块化。
function getExample() {
var a = promiseA(…);
var b = a.then(function(resultA) {
// some processing
return promiseB(…);
});
return Promise.all([a, b]).then(function([resultA, resultB]) {
// more processing
return // something using both resultA and resultB
});
}
而不是在Promise.all
之后的回调中的参数解构,只有在ES6中才可用,在ES5中, then
调用将被许多诺言库(Q,Bluebird,when,...)提供的漂亮的辅助方法取代: .spread(function(resultA, resultB) { …
Bluebird还具有一个专用的join
函数,用一个更简单(更高效)的构造来代替Promise.all
+ spread
组合:
…
return Promise.join(a, b, function(resultA, resultB) { … });
ECMAScript和谐
当然,这个问题也得到了语言设计师的认可。 他们做了很多工作,异步功能建议最终成功实现
ECMAScript 8
你并不需要一个单一的then
调用或回调函数更多,比如在异步函数(即返回时,被称为承诺),你可以简单地等待承诺以直接解决。 它还具有任意的控制结构,如条件,循环和try-catch-clause,但为了方便起见,我们在这里不需要它们:
async function getExample() {
var resultA = await promiseA(…);
// some processing
var resultB = await promiseB(…);
// more processing
return // something using both resultA and resultB
}
ECMAScript 6
在等待ES8时,我们已经使用了非常类似的语法。 ES6带有生成器函数,它允许在任意放置的yield
关键字中分割执行。 这些切片可以独立运行,甚至是异步运行 - 这就是我们在运行下一步之前等待承诺解决方案时所做的。
有专用的库(如co或task.js),但许多promise库也有助手函数(Q,Bluebird,when,...),当你为它们提供一个生成器函数时,为你做这个异步的分步执行产生承诺。
var getExample = Promise.coroutine(function* () {
// ^^^^^^^^^^^^^^^^^ Bluebird syntax
var resultA = yield promiseA(…);
// some processing
var resultB = yield promiseB(…);
// more processing
return // something using both resultA and resultB
});
自从4.0版本开始,这在Node.js中起作用,而且一些浏览器(或其开发版本)确实比较早地支持生成器语法。
ECMAScript 5
但是,如果您希望/需要向后兼容,则不能在没有转译器的情况下使用这些转换器。 目前的工具支持发电机功能和异步功能,例如参见发电机和异步功能的Babel文档。
然后,还有许多其他编译器对JS语言,这些语言致力于缓解异步编程。 它们通常使用类似于await
的语法(例如Iced CoffeeScript),但也有其他类似于Haskell的do
-notation(例如LatteJs,monadic,PureScript或LispyScript)。
同步检查
为变量分配promise-for-later-needed-values,然后通过同步检查获取它们的值。 该示例使用bluebird的.value()
方法,但许多库提供了类似的方法。
function getExample() {
var a = promiseA(…);
return a.then(function() {
// some processing
return promiseB(…);
}).then(function(resultB) {
// a is guaranteed to be fulfilled here so we can just retrieve its
// value synchronously
var aValue = a.value();
});
}
这可以用于尽可能多的值,只要你喜欢:
function getExample() {
var a = promiseA(…);
var b = a.then(function() {
return promiseB(…)
});
var c = b.then(function() {
return promiseC(…);
});
var d = c.then(function() {
return promiseD(…);
});
return d.then(function() {
return a.value() + b.value() + c.value() + d.value();
});
}
链接地址: http://www.djcxy.com/p/9445.html
上一篇: How do I access previous promise results in a .then() chain?
下一篇: What is the explicit promise construction antipattern and how do I avoid it?