当回调中完成大量计算时,事件循环将被阻塞,直到计算完成。这意味着回调将阻塞事件循环 5 秒。
我的解决方案
可以使用生成器函数将控制权交还给事件循环。我将使用一个while loop
运行 3 秒的函数作为长时间运行的回调。
没有生成器功能
let start = Date.now();
setInterval(() => console.log('resumed'), 500);
function loop() {
while ((Date.now() - start) < 3000) { //while the difference between Date.now() and start is less than 3 seconds
console.log('blocked')
}
}
loop();
输出将是:
// blocked
// blocked
//
// ... would not return to the event loop while the loop is running
//
// blocked
//...when the loop is over then the setInterval kicks in
// resumed
// resumed
带有生成器功能
let gen;
let start = Date.now();
setInterval(() => console.log('resumed'), 500);
function *loop() {
while ((Date.now() - start) < 3000) { //while the difference between Date.now() and start is less than 3 seconds
console.log(yield output())
}
}
function output() {
setTimeout(() => gen.next('blocked'), 500)
}
gen = loop();
gen.next();
输出是:
// resumed
// blocked
//...returns control back to the event loop while though the loop is still running
// resumed
// blocked
//...end of the loop
// resumed
// resumed
// resumed
使用 javascript生成器可以帮助运行繁重的计算函数,这些函数会在事件循环仍在计算时将控制权交还给事件循环。
要了解有关事件循环的更多信息,请访问
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Statements/function*
https://davidwalsh.name/es6-generators