【问题标题】:When all AJAX requests complete当所有 AJAX 请求完成时
【发布时间】:2016-08-03 08:41:40
【问题描述】:

我有一个 ajax 请求,它获取一些数据,然后将其拆分为一个数组。数组长度可变。

  var ajax1 = $.ajax({
    url: 'myurl.php',
    type: "GET",
    dataType: "jsonp",
    success: function (data) {

      //create an array

    }

  });

一旦我有了数组,我想遍历它并在每次迭代中运行另一个 AJAX 请求。我将它放在 $.when 中以确保初始 ajax 请求已完成:

  $.when(ajax1).done(
    function() {

      for (i = 0; i < array.length; ++i) {

        $.ajax({
          url: 'anotherurl?=' + myarray[i],
          type: "GET",
          dataType: "jsonp",
          success: function (data) {

            //do stuff here

          }
        });

      }

    }
  )

我的问题是,当 for 循环完成所有 AJAX 请求时,我怎样才能弹出一个消息框?循环结束时的简单alert('complete') 将不起作用,因为 AJAX 是异步完成的。

【问题讨论】:

标签: javascript jquery ajax


【解决方案1】:

从 JQuery 1.5 开始,$.ajax() 返回一个实现了 Promise 接口的对象,因此您可以将所有这些 Promise 存储在一个数组中,然后使用 Promise.all() 等待它们完成。

类似:

  var root = 'http://jsonplaceholder.typicode.com';
  var p = [];

  p.push( $.ajax({url: root + '/posts/1', method: 'GET'}));
  p.push( $.ajax({url: root + '/posts/2', method: 'GET'}));
  p.push( $.ajax({url: root + '/posts/3', method: 'GET'}));
  p.push( $.ajax({url: root + '/posts/4', method: 'GET'}));

  Promise.all(p).then(values => { 
    console.log( 'Ajax responses after they have all finished: ', values); 
  });

请参阅此plnkr 以获取示例。

希望有帮助!

【讨论】:

  • 善用 Promise.all。使用 URL 数组,您可以执行以下操作: const loadUrls = async urls => { let results = []; urls.forEach(url => { results.push($.ajax({url})); }) return await Promise.all(results); }
【解决方案2】:

您也可以使用$.when 来实现此目的。您只需将您发出的所有 AJAX 请求存储在一个数组中,并将 apply() 该数组存储到 $.when。试试这个:

$.when(ajax1).done(function() {
    var requests = [];
    for (i = 0; i < array.length; ++i) {
        requests.push($.ajax({
            url: 'anotherurl?=' + myarray[i],
            dataType: "JSONP",
            success: function (data) {
                // do stuff here
            }
        }));
    }
    $.when.apply($, requests).done(function() {
        console.log('complete');
    });
})

您也可以使用map() 稍微缩短逻辑,但请注意这在

$.when(ajax1).done(function() {
    var requests = array.map(function() {
        return $.ajax({
            url: 'anotherurl?=' + myarray[i],
            dataType: "JSONP",
            success: function (data) {
                // do stuff here
            }
        });
    });
    $.when.apply($, requests).done(function() {
        console.log('complete');
    });
})

【讨论】:

    【解决方案3】:

    jQuery 很快就会在这里抬起它顽固的脑袋。我建议你使用一些更好的东西,比如 Promises,让你在这种情况下有更多的控制权

    const pajax = opts=>
      new Promise((resolve, reject)=>
        $.ajax(opts).done(x => resolve(x)).fail((_,_,err)=> reject(err))
    

    那么你可以像这样使用Promise.all

    pajax({
      url: 'myurl.php',
      type: "GET",
      dataType: "jsonp",
    })
    .then(data => {
      // create your arr
      let arr = ...
    
      return Promise.all(arr.map(x=> {
        return pajax({
         url: 'anotherurl?=' + x,
         type: "GET",
         dataType: "jsonp"
        })
      }))
    })
    .then(data => {
      console.log('this is called after all promises are done'
    })
    .catch(err=> {
      console.error(err)
    })
    

    编辑

    @RoryMcCrossan 的回答很好,如果您想将所有内容都保留在 jQuery 领域中

    【讨论】:

      猜你喜欢
      • 2015-07-17
      • 1970-01-01
      • 2020-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      相关资源
      最近更新 更多