在OOP Javascript ES6中以异步方法循环退出

时间:2017-11-20 17:41:38

标签: javascript oop async-await

我的班级有一个类似这样的方法:

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,我错过了什么?

1 个答案:

答案 0 :(得分:2)

bar1bar2似乎不会返回实际等待任何事情的承诺。 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 && …);
}