为什么 ES6 已经有了生成器,ES2017 还要引入 async/await?

Why does ES2017 introduce async/await when ES6 already has generators?

在阅读 asyncawait 时,我注意到它几乎等同于生成器函数。考虑 this fragment from TypeScript Deep Dive:

Async Await

(...)

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

(...)

Generated JavaScript

You don't have to understand this, but it's fairly simple if you've read up on generators. The function foo can be simply wrapped up as follows:

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

where the wrapToReturnPromise just executes the generator function to get the generator and then use generator.next(), if the value is a promise it would then+catch the promise and depending upon the result call genertor.next(result) or genertor.throw(error). That's it!

它最终成为 "a new feature" 的原因是什么?恕我直言,仅使用某个库中的 wrapToReturnPromise 函数同样好,同时不会增加 JavaScript 本身的复杂性。

注意:它与this question有关,但我在这里问的是"why",而不是"how"。我试着去理解动机。

乍一看,语法相似,您可能会认为代码的行为相似——但存在一些关键差异:

  • 说出你的意思function*yieldasync function 和 [=13 的意思非常不同=],类似于 Subclass.prototype = Object.create(Superclass.prototype); Subclass.prototype.constructor = Subclassclass Subclass extends Superclass

  • 的区别
  • 运算符优先级:你可以await a + await b表示(await a) + (await b),但是yield a + yield b表示yield (a + (yield b))

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

  • 其他论据:也有许多反对async/await的论点——including many people that say that generators are just plain 'better'async/await是走错方向了。

来自ES discussion site不要脸的总结。我鼓励您阅读整个主题,因为它对这个主题有一些非常有趣的讨论。