当ES6已经有生成器时,为什么ES2017会引入async/await?

mik*_*1aj 3 javascript language-design generator async-await ecmascript-2017

在阅读async和时await,我注意到它几乎相当于发电机功能.考虑来自TypeScript Deep Dive的这个片段:

异步等待

(......)

// Not actual code. A thought experiment
async function foo() {
    try {
        var val = await getMeAPromise();
        console.log(val);
    }
    catch(err) {
        console.log('Error: ', err.message);
    }
}
Run Code Online (Sandbox Code Playgroud)

(......)

生成的JavaScript

你不必理解这一点,但如果你已经阅读了生成器,那就相当简单了.该功能foo可以简单地包装如下:

const foo = wrapToReturnPromise(function* () {
    try {
        var val = yield getMeAPromise();
        console.log(val);
    }
    catch(err) {
        console.log('Error: ', err.message);
    }
});
Run Code Online (Sandbox Code Playgroud)

wrapToReturnPromise刚刚执行生成函数来获取generator,然后使用generator.next()如果该值是,promise它会then+ catch的承诺,并根据结果调用genertor.next(result)genertor.throw(error).而已!

它最终成为"新功能"的原因是什么?恕我直言,只是wrapToReturnPromise在某些库中使用该函数同样好,而不会导致JavaScript本身的复杂性.

注意:它与这个问题有关,但在这里我问的是"为什么",而不是"如何".我试着理解动机.

Dan*_*rza 8

乍一看,语法类似,您可能会认为代码的行为类似 - 但有一些关键的区别:

  • 说出你的意思:function*yield意味着什么很大的不同async functionawait,类似于如何Subclass.prototype = Object.create(Superclass.prototype); Subclass.prototype.constructor = Subclass从不同class Subclass extends Superclass

  • 运算符优先级:你可以做await a + await b的意思(await a) + (await b),但yield a + yield b手段yield (a + (yield b))

  • 未来的发展:async/await通过乐观的事务锁定和推测执行为一些非常有趣的工作铺平道路,因为它们(如本线程中所述)原子性边界的显式标记

  • 其他论点:还有许多反驳论据async/await- 包括许多人说发电机只是'更好'而且async/await走向错误.

ES讨论网站无耻地总结.我鼓励你阅读整个主题,因为它有一些关于这个主题的非常有趣的讨论.