ECMAScript和谐
当然,语言设计者也认识到了这个问题。他们做了大量的工作,异步函数提案最终得以通过
ECMAScript 8
您不再需要单个then调用或回调函数,就像在异步函数(在被调用时返回promise)中一样,您可以简单地等待promise直接解析。它还具有任意的控制结构,如条件,循环和try-catch子句,但为了方便起见,我们在这里不需要它们:
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),但也有许多承诺库有辅助函数(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
});
这在Node.js 4.0版本起就可以了,也有一些浏览器(或他们的开发版本)相对较早地支持生成器语法。
ECMAScript 5
然而,如果你想要/需要向后兼容,你就不能在没有转译器的情况下使用它们。当前工具支持生成器函数和异步函数,例如,请参阅关于生成器和异步函数的Babel文档。
此外,还有许多其他的编译到js语言
它们致力于简化异步编程。它们通常使用类似于await的语法(例如Iced CoffeeScript),但也有其他一些具有类似haskell的do-notation(例如LatteJs, monadic, PureScript或LispyScript)。