Javascript async/await和ES6之间的差异与生成器

Javascript async/await和ES6之间的差异与生成器,javascript,node.js,ecmascript-6,generator,ecmascript-next,Javascript,Node.js,Ecmascript 6,Generator,Ecmascript Next,我刚刚读了这篇精彩的文章«»,它清楚地突出了这个函数,它是处理生成器函数的辅助函数: 函数异步(makeGenerator){ 返回函数(){ var generator=makeGenerator.apply(这是参数); 函数句柄(结果){ //结果=>{done:[Boolean],值:[Object]} if(result.done)返回Promise.resolve(result.value); 返回Promise.resolve(result.value).then(function

我刚刚读了这篇精彩的文章«»,它清楚地突出了这个函数,它是处理生成器函数的辅助函数:

函数异步(makeGenerator){
返回函数(){
var generator=makeGenerator.apply(这是参数);
函数句柄(结果){
//结果=>{done:[Boolean],值:[Object]}
if(result.done)返回Promise.resolve(result.value);
返回Promise.resolve(result.value).then(function(res){
返回手柄(生成器下一个(res));
},函数(err){
返回手柄(生成器抛出(err));
});
}
试一试{
返回句柄(generator.next());
}捕获(ex){
退货承诺。拒绝(ex);
}
}
}
我假设这或多或少是
async
关键字用
async
/
await
实现的方式。所以问题是,如果是这样的话,
wait
关键字和
yield
关键字之间到底有什么区别?
wait
是否总是将某件事变成承诺,而
yield
却没有这样的保证?这是我最好的猜测


在本文中,您还可以看到
async
/
await
yield
在生成器中的相似之处,他在文中描述了“spawn”函数。

yield
可以被视为
await
的构建块
yield
获取给定的值并将其传递给调用方。然后,调用方可以使用该值(1)执行它希望执行的任何操作。稍后,调用方可以(通过
generator.next()
)将值返回给生成器,该值将成为
yield
表达式(2)的结果,或者是
yield
表达式(3)抛出的错误

async
-
await
可以考虑使用
yield
。在(1)处,调用方(即
async
-
wait
驱动程序-类似于您发布的函数)将使用与
新承诺类似的算法(r=>r(value)
(注意,不是
promise.resolve
,但这不是什么大问题)将值封装在承诺中。然后,它等待承诺得到解决。如果它满足,它将在(2)处传递已满足的值。如果它拒绝,它将在(3)处将拒绝原因作为错误抛出

因此,
async
-
await
的实用程序是这样一种机器,它使用
yield
将产生的值作为承诺展开,并将其解析值传递回,重复直到函数返回其最终值

wait
关键字和
yield
关键字之间到底有什么区别

wait
关键字仅用于
async函数
s,而
yield
关键字仅用于generator
function*
s。这两个关键字也明显不同——一个返回承诺,另一个返回生成器

wait
是否总是将某件事变成承诺,而
yield
却没有这样的保证

是,
await
将调用
Promise。对等待的值进行解析


yield
只产生生成器之外的值。

好吧,事实证明,
async
/
await
和生成器之间有着非常密切的关系。我相信
async
/
await
将始终建立在生成器之上。如果你看看Babel传输文件的方式
async
/
>等待

巴贝尔说:

this.it('是一个测试'),异步函数(){
const foo=等待3;
const bar=等待新承诺(resolve=>resolve('7');
const baz=bar*foo;
控制台日志(baz);
});
把它变成这个

函数\u异步生成器(fn){
返回函数(){
var gen=fn.apply(这是参数);
返回新承诺(功能(解决、拒绝){
功能步骤(键,参数){
试一试{
var info=gen[key](arg);
var值=信息值;
}捕获(错误){
拒绝(错误);
返回;
}
如果(信息完成){
决心(价值);
}否则{
返回承诺。解析(值)。然后返回(函数(值){
返回步骤(“下一步”,值);
},函数(err){
返回步骤(“抛出”,错误);
});
}
}
返回步骤(“下一步”);
});
};
}
this.it('是一个测试',_asyncToGenerator(函数*(){//resolve(7));
const baz=bar*foo;
控制台日志(baz);
}));
你来算吧

这使它看起来像是
async
关键字就是包装器函数,但如果是这样,那么
wait
就变成了
yield
,当它们成为本机时,可能会有更多的内容

你可以在这里看到更多的解释:

在许多方面,生成器是async/await的超集。目前,async/await的堆栈跟踪比最流行的基于生成器的异步/await类lib更干净。您可以使用生成器实现自己的async/await风格,并添加新功能,比如在非承诺上内置对
yield
的支持,或者在RxJS可观察对象上构建它


因此,简而言之,生成器为您提供了更大的灵活性,基于生成器的lib通常具有更多的特性。但是async/await是该语言的核心部分,它是标准化的,在您的管理下不会改变,并且您不需要库来使用它。关于async/await和Generator之间的区别,我有一个更详细的介绍。

试试这个测试程序,我曾经用它来理解async
/
async