【问题标题】:How to make for loop wait until Async call was successful before to continue如何让 for 循环等到异步调用成功后再继续
【发布时间】:2014-05-23 14:48:27
【问题描述】:

您好,我正在使用 for 循环和异步 ajax 调用为我的本地商店创建批量更新。

我的问题是,即使我的 ajax 调用仍未成功完成,我的循环仍在继续。

在继续循环之前,我们如何设法使 for 循环等待单元成为 ajax 响应的响应?

感谢任何帮助。谢谢!!!

下面是我的示例代码:

var counter =0;
var totalRow = 3000;
for (var i = 0, l = totalRow; counter <= l; i++) {

    var defectssurl = 'https://test.com/mywcf.svc/GetListAllPaging?id=' + counter;

    Ext.Ajax.request({
        url: defectssurl,
        method: "POST",
        params: '',
        success: function (resp) {

            console.log("load first 500 records");
            var data = Ext.JSON.decode(resp.responseText); //encode Json List

            if (counter == 0) {
                defectsLocalStore.getProxy().clear();
                // Also remove all existing records from store before adding
                defectsLocalStore.removeAll();
            }

            Ext.Array.each(data, function (record) {
                counter = counter + 1;
                defectsLocalStore.add(record);
            });

            defectsLocalStore.sync(); // The magic! This command persists the records in the store to the browsers localStorage

            //records is now same as the total records
            if (counter >= totalRow) {
                pCallback();
            }

            //continue loop
        },
        headers: {
            'Content-Type': 'application/json; charset=utf-8'
        },
        failure: function (resp) {

        }
    });

}

【问题讨论】:

  • 循环不能等待任何异步,因为 Javascript 是单线程的。在循环结束并返回到主事件循环之前,不会发生异步更新。
  • 不要循环执行它们,而是让行 isuccess 函数发送行 i+1 的 AJAX 请求。
  • 你可以尝试使用promise。不执行 AJAX 调用,而是返回一个 promise 数组。然后,您可以使用then 在数组中的所有承诺都完成时执行
  • 如果你想一次运行一次 ajax 调用,你根本不能使用for 循环。相反,您必须在前一个的成功处理程序中启动下一个 ajax 调用。请参阅stackoverflow.com/questions/22952965/…,了解今天早些时候发布的执行此操作的示例。

标签: javascript ajax sencha-touch


【解决方案1】:

请不要使用“for循环”。相反,在成功回调中增加计数器并重新触发自身。如下所示。

function mySyncFunction (counter, totRecords){
   if(counter === undefined) 
     counter = 0;   
   if(counter >=totRecords) return;

   var defectssurl = 'https://test.com/mywcf.svc/GetListAllPaging?id=' + counter;
   Ext.Ajax.request({
     url:defectssurl,
        // snip // your code here
     success: function (resp) {
        // snip // your code here
        counter++;
        mySyncFunction(counter, totRecords);
     }
     // snip // your code here
});

【讨论】:

  • 请不要推荐async: false。我从未见过这是实现任何 Ajax 调用的最佳方式,或者更糟糕的是,它是实现一系列 Ajax 调用的最佳方式。它会在 ajax 调用期间锁定浏览器并阻止用户输入。
  • Async 真的不推荐,但感谢 Abhi,你的逻辑适用于我:D
  • 同意。我会取消那个选项。
猜你喜欢
  • 1970-01-01
  • 2021-12-27
  • 2017-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-17
  • 1970-01-01
  • 2011-07-04
相关资源
最近更新 更多