【问题标题】:Wait until unknown number of $.get are completed, then refresh page等到未知数量的$.get完成,然后刷新页面
【发布时间】:2016-11-03 04:57:32
【问题描述】:

我正在运行一段 javascript 来运行 Ajax 调用(以 XML 形式返回),处理该 XML,然后对 XML 中找到的每个“记录”执行另一个 Ajax 调用(删除记录),然后一旦所有的东西都有完成,刷新页面。

这很好用,但我无法让 Javascript 等到所有迭代 Ajax 调用都完成后再刷新页面。

在刷新页面之前等待所有迭代调用完成的最佳方法是什么?

任何“AVMI_”变量都在别处定义。

var x = $.get(AVMI_childDB, {   //******* INITIAL AJAX *******
    act: "API_DoQuery",
    query: AVMI_query, 
    clist: "3",
    includeRids: "1"
});

x.then(function(xml1) {
    console.dirxml(xml1);
    $(xml1).find('record').each(function(){
        var AVMI_record = $(this); 
        var AVMI_childRID = AVMI_record.attr("rid");
        console.log(AVMI_childRID);
        var y = $.get(AVMI_childDB , {   //******* ITERATIVE AJAX CALL ******* 
            act: 'API_DeleteRecord', 
            rid: AVMI_childRID
        });
        y.then(function(xml2) {
            console.dirxml(xml2);
        });
    });
    location.reload();
});

【问题讨论】:

  • 您可以使用第一个请求来存储找到多少记录的变量计数,然后在每次完成时增加计数。如果当前计数 +1 等于您之前的计数,请刷新。
  • 我想我也可以这样做,谢谢指出!

标签: javascript jquery ajax promise


【解决方案1】:

您需要收集您在循环中创建的每个承诺,然后您可以使用$.when() 知道它们何时全部完成:

var x = $.get(AVMI_childDB, {   //******* INITIAL AJAX *******
    act: "API_DoQuery",
    query: AVMI_query, 
    clist: "3",
    includeRids: "1"
});

x.then(function(xml1) {
    console.dirxml(xml1);
    var promises = [];
    $(xml1).find('record').each(function(){
        var AVMI_record = $(this); 
        var AVMI_childRID = AVMI_record.attr("rid");
        console.log(AVMI_childRID);
        var y = $.get(AVMI_childDB , {   //******* ITERATIVE AJAX CALL ******* 
            act: 'API_DeleteRecord', 
            rid: AVMI_childRID
        }).then(function(xml2) {
            console.dirxml(xml2);
        });
        promises.push(y);
    });
    $.when.apply($, promises).then(function() {
        location.reload();
    })

});

使用.map() 并让 jQuery 为您收集 Promise 可能会更简洁一些:

var x = $.get(AVMI_childDB, {   //******* INITIAL AJAX *******
    act: "API_DoQuery",
    query: AVMI_query, 
    clist: "3",
    includeRids: "1"
}).then(function(xml1) {
    console.dirxml(xml1);
    var promises = $(xml1).find('record').map(function(){
        var AVMI_record = $(this); 
        var AVMI_childRID = AVMI_record.attr("rid");
        console.log(AVMI_childRID);
        return $.get(AVMI_childDB , {   //******* ITERATIVE AJAX CALL ******* 
            act: 'API_DeleteRecord', 
            rid: AVMI_childRID
        }).then(function(xml2) {
            console.dirxml(xml2);
        });
    }).get();
    $.when.apply($, promises).then(function() {
        location.reload();
    })

});

【讨论】:

  • 为什么投反对票?这个答案有什么不正确的?它显示了比其他答案更完整的解决方案,并且始终使用 jQuery 进行承诺管理,因此即使在较旧的浏览器中也可以使用。
  • 感谢您的回答。我已经进行了一些研究,并且基本上决定按照您在第一个示例中所做的方式进行操作,但无法完全写出来。您的回答解决了我的问题,让我可以继续其他类似的任务!谢谢一百万!
【解决方案2】:

由于每个 .get() 都会返回一个 Promise,我建议您将这些 Promise 推送到一个数组中。然后在你的函数结束时你可以简单地做Promise.all(myArrayOfPromises).then(refreshThePage)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-12-12
    • 2011-11-07
    • 1970-01-01
    • 2013-12-25
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    相关资源
    最近更新 更多