繁体   English   中英

检测AJAX呼叫循环何时完成

[英]Detecting When a Loop of AJAX Calls is Done

我有一个网页,可以将无限数量的项目提交回服务器进行处理。

我决定使用AJAX调用将这些项目以25个为一组提交给Web服务。 所以我的循环看起来像这样:

// Submit elements
for (var i = 0; i < ids.length; i += 25) {

    var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));

    $.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
    .done(function (result, statusText, jqxhr) {

        // TODO: Update progress

    })
    .always(function () {
        // TODO: Test for error handling here
    });
}

到目前为止,这似乎是对的。 但是,当所有处理完成后,我想刷新页面。 鉴于上面的代码,我没有看到在最后一次AJAX调用完成时执行任务的简单方法。

由于$.post()是异步的,因此该循环将在AJAX调用之前完成。 由于AJAX调用可以以与提交时不同的顺序完成,因此我不能简单地测试我上次提交的调用何时完成。

我怎么知道这段代码什么时候完成?

你可以利用jQuery的承诺来做到这一点。 一般工作流程涉及将每个promise添加到数组中,然后使用jQuery应用该数组以便在返回所有promise 执行另一个回调。

这样的事情应该有效:

var promises = []
for (var i = 0; i < ids.length; i += 25) {

    var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));

    var promise = $.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
    .done(function (result, statusText, jqxhr) {

        // TODO: Update progress

    })
    .always(function () {
        // TODO: Test for error handling here
    });

    promises.push(promise);
}

/*
    Note, the "apply" function allows one to unwrap an array to parameters for a
    function call. If you look at the jQuery.when signature, it expects to be 
    called like: $.when(promise1, promise2, promise3). Using .apply allows you 
    to satisfy the signature while using an array of objects instead.

    See MDN for more information: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
*/
$.when.apply($, promises)
    .done(function() {
        console.log("All done!") // do other stuff
    }).fail(function() {
        // something went wrong here, handle it
    });

你可以通过推送数组中的所有promises,并使用$.when来确定它们何时完成

var ajaxArr = [];

for (var i = 0; i < ids.length; i += 25) {

    var productIds = {
        importProductIds : ids.slice(i, Math.min(i + 25, ids.length - 1))
    }

    ajaxArr.push(
        $.post('/Services/ImportProducts.asmx/ImportProducts', productIds, function(result, statusText, jqxhr) {
            // TODO: Update progress
        })
    );
}


$.when.apply(undefined, ajaxArr).done(function() {

    window.location.href = 'something'

});

您可以设置一个计数,该计数等于您必须处理的循环数,然后从ajax请求返回时,递减计数器并检查它是否为零。 当它达到零时,您可以刷新页面

var remains = ids.length;

// Submit elements
for (var i = 0; i < ids.length; i += 25) {

    var productIds = ids.slice(i, Math.min(i + 25, ids.length - 1));

    $.post('/Services/ImportProducts.asmx/ImportProducts', JSON.stringify({ importProductIds: productIds }))
    .done(function (result, statusText, jqxhr) {

        // TODO: Update progress

    })
    .always(function () {

       // TODO: Test for error handling here

       remains--;
       if ( remains===0 ) {

             // TODO: refresh here
       }
    });
}

只计算完成了多少次回调; 虽然回调是异步的,但代码在一个线程中运行,因此它们将按顺序调用,您可以安全地假设当count == 25您已完成。

暂无
暂无

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

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