Promise循环,每次执行一些事情,一些其他事情只执行一次

时间:2014-04-10 01:52:53

标签: javascript loops recursion return promise

我试图执行以下操作:

我有一个函数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;
}

有没有办法实现这一目标?

2 个答案:

答案 0 :(得分:1)

在这里做两件事很重要:

  • Promises / A +以递归方式展开,以便您可以从处理程序返回复合承诺。
  • 承诺链。很少见的是你在使用promises时需要延迟对象的情况。

一旦我们理解了这两件事,我们就可以创建一个更简单的循环&#34;因为我们可以简单地返回一个&#34;复合循环&#34;保证我们通过那个链接:

// 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;
};

在我看来,这比检查布尔值和多余延迟对象的递归调用要简单得多。它利用了承诺的优势,而不是回归到回调中。

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

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

与承诺一样有效:

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;
}

答案 1 :(得分:0)

我不知道这是否是最佳选择,但我会将下一组的布尔变量发送给true。

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;
}