繁体   English   中英

在递归异步ajax调用之后执行函数

[英]Execute a function after the recursive asynchronous ajax calls

我需要在递归异步ajax调用之后执行一个函数。 我有:

var tree = [1, 2 ,3, 4];

recursion(0);

function recursion(i) {
    $.ajax('http://example.com/' + tree[i])
        .done(function (data) {
        // data is array
        ++i;
        if (tree[i] !==undefined) {
            $.each(data, function () {
                recursion(i);
            });
        }
    });
}

我想在完成所有通话完成以下操作:

recursion(0).done(function () {alert('All calls are done!')});

我知道,我应该使用JQuery的$ .Deferred,但是ajax调用返回诺言也是如此。 我正在尝试使用$ .Deferred,但是在这个地方遇到了循环问题:

     $.each(data, function () {
         recursion(i);
     });

请帮我。

您将需要执行以下操作:

function recursion(i) {

    return $.ajax('http://example.com/' + tree[i])
        .then(function (data) {
            // data is array
            ++i;
            if (tree[i] !==undefined) {

                // get an array of promises
                var promises = $.map(data, function () {
                    return recursion(i);
                });

                // return the `when` promise from the `then` handler 
                // so the outer promise is resolved when the `when` promise is
                return $.when.apply($, promises);
            } else {
                // no subsequent calls, resolve the deferred
            }
        });
}

目前未经测试,但至少可以为您提供这个想法。 基本上,只有解决了所有后续调用后,您才解决延迟的问题。

我正在尝试使用$ .Deferred

好!

但是我在这个地方遇到了循环问题: $.each(data, recursion)

每个recursion(i)调用都会返回一个promise,因此当我们将它们踢开后,我们将获得一个promises集合。 现在,我们可以使用$.when 等待所有它们 ,并获得所有结果的承诺。

现在,我们使用then链接在ajax调用之后将此循环执行链接起来,以便我们可以为该递归步骤的最终结果返回承诺。

function recursion(i, x) {
    return $.ajax('http://example.com/' + tree[i] + x).then(function (data) {
        if (++i < tree.length)
            // get an array of promises and compose all of them
            return $.when.apply($, $.map(data, function(d) {
                return recursion(i, d);
            }));
        else // at the innermost level
            return data; // get the actual results
    }); // and return a promise for that
}

为简单起见,您可以在.done中运行一个检查i值的函数,如果该值等于树的长度(减1),则运行该函数。

抱歉,它不涉及异步性质...而是...创建一个变量,该变量跟踪已完成的数目并与数组中的数目进行比较。 相等时,运行您的函数。

编辑, deferred jquery, promise达到要求实际上并不需要。 请参阅下面的Bergi评论和链接。

尝试(此模式; 不使用 jquery.deferredpromise的)

   (function recursion() {
        var tree = [1, 2 ,3, 4]
        , results = []
        , dfd = function(res) {
            alert('All calls are done!');
            console.log(res)
        };

    $.each(tree, function(k, v) {
        $.ajax("http://example.com/" + v)
        .done(function (data, status, jqxhr) {
        // data is array
          results.push([data, status, jqxhr.state()]);
            if (results.length === tree.length) {
              dfd(results);          
            }
        });

    });

    }());

jsfiddle http://jsfiddle.net/guest271314/nvs0jb6m/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM