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
关键字仅用于generatorfunction*
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