为什么 ES6 已经有了生成器,ES2017 还要引入 async/await?
Why does ES2017 introduce async/await when ES6 already has generators?
在阅读 async
和 await
时,我注意到它几乎等同于生成器函数。考虑 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*
和 yield
与 async function
和 [=13 的意思非常不同=],类似于 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
的论点——including many people that say that generators are just plain 'better'和async/await
是走错方向了。
来自ES discussion site不要脸的总结。我鼓励您阅读整个主题,因为它对这个主题有一些非常有趣的讨论。
在阅读 async
和 await
时,我注意到它几乎等同于生成器函数。考虑 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 thegenerator
and then usegenerator.next()
, if the value is apromise
it wouldthen
+catch
the promise and depending upon the result callgenertor.next(result)
orgenertor.throw(error)
. That's it!
它最终成为 "a new feature" 的原因是什么?恕我直言,仅使用某个库中的 wrapToReturnPromise
函数同样好,同时不会增加 JavaScript 本身的复杂性。
注意:它与this question有关,但我在这里问的是"why",而不是"how"。我试着去理解动机。
乍一看,语法相似,您可能会认为代码的行为相似——但存在一些关键差异:
说出你的意思:
function*
和yield
与async function
和 [=13 的意思非常不同=],类似于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
的论点——including many people that say that generators are just plain 'better'和async/await
是走错方向了。
来自ES discussion site不要脸的总结。我鼓励您阅读整个主题,因为它对这个主题有一些非常有趣的讨论。