$ .Deferred.then()函数是否允许动态调用函数的未知时间?

时间:2014-09-03 18:04:19

标签: javascript jquery jquery-deferred

我在jQuery Deferred and Promise for sequential execution of synchronous and asynchronous funcitons的谷歌搜索中找到了这个脚本。

这可以解决我在以便宜顺序执行脚本时的问题。但是我用then()函数的问题是我无法知道有多少时间可以调用这个函数。我可以调用函数a()3次,下次,我可以调用它20次,等等。那么,那就不能用then()了。 then()函数不允许数组堆栈。那么,你们做了什么让这个概念有用呢?

fucntion a(counter)
{
    $deferred = $.Deferred();

    //Run some scripts here...
    alert(counter);

    $deferred.resolve();
    return $deferred;
}
function Test()
{
    var d = $.Deferred(), 
    p=d.promise();
    p.then(a(0)).then(a(1)).then(a(2));
    d.resolve();
    return d;
}

Test().done(function(){ alert('done'); }).fail(function() { alert('fail'); });

2 个答案:

答案 0 :(得分:2)

我认为你问的是如何连锁和未知数量的电话。在这种情况下,您可以轻松循环并继续添加更多.then。例如:

for (var i=0; i < someLimit; i++) {
    p = p.then(a(i));
}

这将链接调用,以便一个接一个地调用它们。如果您希望它们并行执行,那么@ jantimon建议使用.when是可行的方法。

这是因为链接的工作原理。对.then的调用会返回一个承诺,以便您可以再次对返回的承诺调用.then。请参阅:http://api.jquery.com/deferred.then/

答案 1 :(得分:1)

您可以使用jQuery.when 请注意,这将同时执行多个异步操作:

jsFiddle Demo

给定a函数返回异步承诺:

function a(counter, $target) {
    var $deferred = $.Deferred();
    setTimeout(function () {
        $target.text($target.text() + ' ' + counter);
        $deferred.resolve();
    }, 1000);
    return $deferred;
}

同时:

function Test1() {
    return $.when($.map([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (val, i) {
        return a(i, $('#test1'));
    }));
}

Test1().done(function () {
    $('#test1').css('font-weight', 'bold');
}).fail(function () {
    alert('fail');
});

要按顺序运行它,您需要一个promiseLoop帮助程序:

function promiseLoop(arr, callback) {
    return arr.reduce(function (previousPromise, val, i) {
        return previousPromise.then(function (resultArray) {
            return $.when(callback(val, i)).then(function (res) {
                return resultArray.concat([res]);
            });
        });
    }, $.when([]));
}

function Test2() {
    return promiseLoop([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function (val, i) {
        return a(i, $('#test2'));
    });
}


Test2().done(function () {
    $('#test2').css('font-weight', 'bold');
}).fail(function () {
    alert('fail');
});