用Q循环暂停

时间:2014-04-24 08:30:02

标签: jquery promise q

我正在使用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();

1 个答案:

答案 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()承诺,以便在您不再暂停时解决。