My class has a method that does something like this:
async foo(..., callback){
do{
for(...){
await bar1();
await bar2();
}
}
while(...);
callback();
}
I want to be able to interrupt the loop on command, so this was my approach at it:
async foo(..., callback){
this.stop = false; // Reset the property
do{
for(...){
await bar1();
await bar2();
}
}
while(!this.stop && ...);
callback();
}
stopTheLoop(){
this.stop = true;
}
And it looked fine to me. So I test it like:
myObject.foo(..., () => {
console.log("Finished!");
});
console.log("Async test");
setTimeout(() => {
myObject.stopTheLoop();
}, 1000);
The behaviour is that i see printed "Async test", which means that the foo() call is correcrly not blocking code execution on the main thread, so i think it's safe to say that the setTimeout function gets called. But the do-while loop never ends, and i never see my "Finished!" callback.
I might not have fully understood async/await in ES6, what am I missing?
bar1
and bar2
appear not to return promises that actually wait for anything. await
ing a plain value is equivalent to Promise.resolve().then(…)
, which will by asynchronous enough to continue with console.log("Async test");
but otherwise goes into a loop of running promise tasks, not allowing timeouts and other macro tasks to interrupt it. this.stop
never changes because the timeout callback never gets a chance to run. Have a look at What determines the call order of deferred function using promises or setTimeout? and Difference between microtask and macrotask within an event loop context for details.
You can fix this by putting a short actual timeout in your loop to make it asynchronous:
async foo(…) {
this.stop = false; // Reset the property
do {
for(…) {
bar1();
bar2();
await new Promise(resolve => setImmediate(resolve));
}
} while (!this.stop && …);
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.