我的班级有一个类似这样的方法:
async foo(..., callback){
do{
for(...){
await bar1();
await bar2();
}
}
while(...);
callback();
}
我希望能够在命令中断循环,所以这是我的方法:
async foo(..., callback){
this.stop = false; // Reset the property
do{
for(...){
await bar1();
await bar2();
}
}
while(!this.stop && ...);
callback();
}
stopTheLoop(){
this.stop = true;
}
它对我来说很好看。 所以我测试它就像:
myObject.foo(..., () => {
console.log("Finished!");
});
console.log("Async test");
setTimeout(() => {
myObject.stopTheLoop();
}, 1000);
行为是我看到打印"异步测试",这意味着foo()调用正确地阻止了主线程上的代码执行,所以我认为可以说是安全的调用setTimeout函数。但是do-while循环永远不会结束,我永远不会看到我的"完成!"回调。
我可能没有完全理解ES6中的async / await,我错过了什么?
答案 0 :(得分:2)
bar1
和bar2
似乎不会返回实际等待任何事情的承诺。 await
一个普通值相当于Promise.resolve().then(…)
,它将通过异步足以继续console.log("Async test");
,但否则会进入运行承诺任务的循环,不允许超时和其他宏任务打断它。 this.stop
永远不会更改,因为超时回调永远不会有机会运行。有关详细信息,请查看What determines the call order of deferred function using promises or setTimeout?和Difference between microtask and macrotask within an event loop context。
你可以通过在循环中设置一个短暂的实际超时来解决这个问题,使其异步:
async foo(…) {
this.stop = false; // Reset the property
do {
for(…) {
bar1();
bar2();
await new Promise(resolve => setImmediate(resolve));
}
} while (!this.stop && …);
}