首页 > 解决方案 > 如何遍历多个 ajax 请求,然后在一切完成后执行代码?

问题描述

让我先说我已经在网上进行了一系列搜索,但似乎无法将其拼凑起来。

要求:使用 jQuery :(

单击时,我正在使用.getJSON调用来获取具有多个图层的对象。

以下是数据示例:

 myObj = {
title: 'some name',
items: [
    {
        name: 'item-1',
        url: '/item-1'
    },
    {
        name: 'item-2',
        url: '/item-4'
    },
    {
        name: 'item-3',
        url: '/item-4'
    },
    {
        name: 'item-4',
        url: '/item-4'
    },
]

}

我想遍历所有的 url,并对.ajax它们调用一个操作,然后将我得到的新数据存储在它们各自的对象中。

它看起来像这样:

myObj = {
title: 'some name',
items: [
    {
        name: 'item-1',
        url: '/item-1',
        properties: {//whole new set of data from url}
    },
    {
        name: 'item-2',
        url: '/item-4',
        properties: {//whole new set of data from url}
    },
    {
        name: 'item-3',
        url: '/item-4',
        properties: {//whole new set of data from url}
    },
    {
        name: 'item-4',
        url: '/item-4',
        properties: {//whole new set of data from url}
    },
]

}

一旦所有这些都完成并且每个对象都有这个新的数据位,然后我想对 做一些事情myObj,比如将它渲染到一个 jquery 模板(呃),但是新数据必须在每个项目的内部。

这是我到目前为止所拥有的:

var myItems = myObj.items;
$(myItems).each(function(index, item) {    
      var itemUrl = '/somestuff/' + item.url + '.js';
      $.getJSON(itemUrl).done(function(itemData) {
        item.data = itemData;                    
      });
    }).promise().done(function() {//render data to template})

我遇到的唯一问题是,有时模板呈现时数据还不存在(item.properties),因此无法呈现未定义。

我尝试过不成功的链接.done(),现在遇到了 using .when(),但不知道如何编写代码行以使其.when()正常工作。

任何帮助表示赞赏,我很乐意澄清细节。

标签: javascriptjqueryajaxpromise

解决方案


如果您捕获每个 AJAX 请求生成的 Promise(实际上是一个 jQuery Deferred 对象),并将它们添加到一个数组中,那么您可以调用.when()以在所有 Promise 解决后执行一些代码。像这样的东西(未经测试):

var myItems = myObj.items;
var promises = [];
$(myItems).each(function(index, item) {    
  var itemUrl = '/somestuff/' + item.url + '.js';
  var p = $.getJSON(itemUrl);
  p.then(function(itemData) {
    item.data = itemData;
    return itemData;
  });
  promises.push(p);
});

$.when.apply($, promises).then(function() { //render data to template...

这可能比链接 done() 回调更可取,因为它仍然允许请求并行执行,这可能会更快(尽管这在某种程度上取决于服务器,但这是一个单独的问题)。


推荐阅读