在循环中使用 jQuery deferred 和 promise

Using jQuery deferred and promise inside loop

这就是我想要实现的目标,

我有一个排序数组,我将其传递给每个 jQuery。每个里面都有一个 ajax 调用,它会获取我想要的数据,并且每次都会推入另一个数组(我们称之为 allJsonData)。最后我显示 allJsonData。 问题是每当我显示 allJsonData 时,元素总是显示不一致(不是 alphabetically/random 顺序)。我希望 allJsonData 按字母顺序显示(首先是 AList 数据,其次是 BList 数据,第三是 CList 数据,依此类推)。 我是 jQuery deferred and promise 的新手。提前致谢。

var sortedArray = [AList, BList, CList, DList];
var promises = [];
var allJsonData = [];
$.each(sortedArray, function (index, value) {
var dfd = $.Deferred();
var url = _spPageContextInfo.webAbsoluteUrl  + ('/_api/Web/Lists/GetByTitle(' + "'" + value + "'" + ')/Items? + "SomeFilterParameters";

//AJAX CALL HERE//
.done(
  function (approvedListItems) {
    if (approvedListItems.d.results.length != 0) {
      $.each(approvedListItems.d.results, function (i, col) {
        allJsonData.push(col);//Push into master array
      });
    }//If closed
    dfd.resolve(allJsonData);
  }
);//Done closed
  promises.push(dfd);
});//jQuery Each closed
return $.when.apply($, promises).promise();

/****AJAX 呼叫****/

getListItems: function(url) {       
  var dfd = $.Deferred();
    $.ajax({
      url: url,
      type: "GET",
      headers: {
        "accept": "application/json;odata=verbose",
      },
    success: function (data) {
      dfd.resolve(data);
    },
    error: function (error) {
      dfd.reject(sender, args, "Error retrieving items");
    }
  });
  return dfd.promise();         
},

我想你可以做这么简单的事情:

var sortedArray = [AList, BList, CList, DList];

Promise.all(sortedArray.map(function(value) {
    var url = ...;
    return getListItems(url);
})).then(function(results) {
    // results is an array of results from AList, BList, CList, DList in order
    let allJsonData = [];
    results.forEach(function(approvedListItems) {
        allJsonData.push.apply(allJsonData, approvedListItems.d.results);
    });
    // process allJsonData here
});

// simplify getListItems like this
getListItems: function(url) {       
    return $.ajax({
        url: url,
        type: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
        }
    });
},

这里的一般想法是您为 sortedArray 中的每个项目获得一个原始列表(不处理其中的子结果)。使用 Promise.all()$.when(),您将按顺序获得原始列表。然后,在您拥有所有原始列表之后,您可以按顺序处理它们并按顺序构建 allJsonData 结构。

此外,您可以从 getListItems() 中删除 promise 反模式。 $.ajax() 已经 returns 一个承诺,因此无需将其包装在另一个承诺中。

如果你真的愿意,你可以将它转换为使用 $.when() 而不是 Promise.all(),但是使用 $.when() 更复杂,因为它需要参数和 returns 个结果。

此外,url 变量中的 Javascript 字符串语法有问题。我不知道你打算在那里做什么,所以我不确定该建议什么,但你也需要解决这个问题。