我已经将我的代码重组为Promise,并构建了一个美妙的长而 扁平的 Promise 链 ,由多个.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? }); }
当然,这个问题也得到了语言设计者的认可。他们做了很多工作,异步函数提案最终成为了
您不再需要单个then调用或回调函数,因为在异步函数中(在被调用时返回一个 Promise),您可以简单地等待 Promise 直接解析。它还具有任意控制结构,例如条件、循环和 try-catch 子句,但为了方便起见,我们在这里不需要它们:
then
async function getExample() { var resultA = await promiseA(…); // some processing var resultB = await promiseB(…); // more processing return // something using both resultA and resultB }
在我们等待 ES8 时,我们已经使用了一种非常相似的语法。ES6 带有生成器函数,它允许在任意放置的yield关键字处将执行分成几部分。这些切片可以彼此独立运行,甚至异步运行——这正是我们想要在运行下一步之前等待承诺解决时所做的事情。
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 中确实有效,还有一些浏览器(或其开发版)相对较早地支持生成器语法。
但是,如果您想要/需要向后兼容,则不能使用没有转译器的那些。当前工具支持生成器函数和异步函数,例如参见 Babel 关于生成器和异步函数的文档。
然后,还有许多其他 专门用于简化异步编程的 compile-to-JS 语言。它们通常使用类似于await, 的语法(例如Iced CoffeeScript),但也有其他具有类似 Haskell 符号的do语法(例如LatteJs、monadic、PureScript或LispyScript)。
await
do