我正在使用Q来对某些文本行进行jQuery后续处理(demo)。现在我添加了一个暂停按钮暂时停止forEach
循环内的处理,但是如果我在promise.delay(300)
循环内添加while
(请参阅下面的部分代码),我的浏览器会挂起。如何使用Q在isPaused
循环中的布尔forEach
上实现条件暂停?
var promise = new Q();
promise = promise.then(function () {
lines.forEach(function (item) {
// Browser starts to hang here if isPaused == true
promise = promise.then(function () {
while (isPaused) {
promise = promise.delay(300);
}
});
// The following does not work either
// while (isPaused) {
// promise = promise.delay(300);
//}
// The following does not work either
// while (isPaused) {
// Q.delay(300);
//}
if (item[0] == '%') {
promise = promise.then(function ()
{ return addPrompt(wnd); })
promise = promise.then(function ()
{ return addInput(item.substr(1)); })
}
else {
promise = promise.then(function ()
{ return addOutput(item, wnd); })
}
});
promise = promise.then(function ()
{ return addPrompt(wnd); })
});
promise.done();
答案 0 :(得分:0)
在这种情况下,Promise仍然是异步的。 while(true)
中的循环将继续执行,同时不会运行其他代码。
在简单的旧浏览器JavaScript中,您根本无法拥有while(condition) { /* block that does not change 'condition' /* }
。在您的情况下更改isPaused的代码永远不会有机会执行。 (好吧,你可以使用ES6生成器让你明确地控制,但这就是OT)。
你需要递归链接承诺。
promise = promise.then(function pollUntil(){
return Q.delay(300).then(function(){
// recursively chain the continuation here this will check every 300 ms
// rather than freeze the code.
return isPaused ? pollUntil() : true;
});
});
这读作:使用pollUntil继续当前操作,延迟300毫秒,然后重复(调用自身),直到isPaused不再为真。
注意,您不能将.then
添加到外部承诺,因为您(或者可能需要在更一般的情况下)链接到它。
当然,最好设置pause()
承诺,以便在您不再暂停时解决。