【问题标题】:Promise loop that executes some things every time and some other things only oncePromise 循环,每次都执行一些事情,而另一些事情只执行一次
【发布时间】:2014-05-23 12:34:45
【问题描述】:

我正在尝试执行以下操作:

我有一个函数looper(),它根据条件调用自己。

我希望其中的某些部分只执行一次,而其他一些部分在每次调用时执行。

我不知道这是否是最好的方法,但我想不出别的办法,而且这不起作用。

var stopper = 3;

looper().then(function() {
    console.log('This should happen only once');
});

function looper(d) {
    if (!d)
        var d = when.defer();  // recycled promise

    console.log('This should happen EVERY time looper() is called');

    next();

    console.log('This shouldn’t happen if looper() is called again by next().');

    function next() {
        if (--stopper <= 0) {
            d.resolve();
        } else {
            looper(d)
            // if only next() could return a `return` 
            // so that looper() returns/exits based on this if condition ... 
            // return return
        }
    }

    return d.promise;
}

有什么方法可以实现吗?

【问题讨论】:

  • 您可以向它传递一个参数,表明它是在内部调用的,类似于您对 d 所做的操作。

标签: javascript loops recursion return promise


【解决方案1】:

我不知道这是否是最好的选择,但我会从下一组发送一个布尔变量为真。

function looper(d, rerun) {
    if (!d)
        var d = when.defer();  // recycled promise

    console.log('This should happen EVERY time looper() is called');

    next();
    if(rerun){
        console.log('This shouldn’t happen if looper() is called again by next().');
    }
    function next() {
        if (--stopper <= 0) {
            d.resolve();
        } else {
            looper(d, true)
           // if only next() could return a `return` 
           // so that looper() returns/exits based on this if condition ... 
           // return return
        }
    }

    return d.promise;
}

【讨论】:

    【解决方案2】:

    这里有两点很重要:

    • Promises/A+ 递归解包,因此您可以从处理程序返回复合承诺。
    • 承诺链。在使用 Promise 时需要延迟对象的情况很少见。

    一旦我们理解了这两件事,我们就可以创建一个更简单的“循环”,因为我们可以简单地返回一个我们通过 then 链接的“复合循环”承诺:

    // a recursive loop:
    function looper(times){
        var p = when.try(function(){
             console.log('This should happen EVERY time looper() is called');
             console.log('This shouldn’t happen if looper() is called again by next().');
        });
        for(var i = 0;i < times; i++){
            p = p.then(function(){
                 console.log('This should happen EVERY time looper() is called');
            });
        }
        return p;
    };
    

    以我的拙见,这比检查布尔值和多余的延迟对象的递归调用要简单得多。它利用了 Promise 的优势,而不是退回到回调中。

    现在如果你想要一个只在第一次做某事的函数,你可以这样做:

    function initOnce(){
        if(!initOnce.wasCalled){ // functions are objects in JS
             // initial actions
             initOnce.wasCalled = true;
        }
        // other actions
    }
    

    这与 promise 一样有效:

    function initOnce(){
        var p = when.try();
        if(!initOnce.wasCalled){ // functions are objects in JS
             // initial actions
             p = p.then(initialHandler);
             initOnce.wasCalled = true;
        }
        // other actions
        p = p.then(otherActions);
        return p;
    }
    

    【讨论】:

      猜你喜欢
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2022-07-06
      • 2018-06-18
      • 2013-08-12
      • 1970-01-01
      相关资源
      最近更新 更多