【问题标题】:jQuery wait for two separate AJAX calls for each iteration to complete before completingjQuery 在完成之前等待每次迭代完成的两个单独的 AJAX 调用
【发布时间】:2020-10-12 23:07:32
【问题描述】:

我整天都在为此苦苦挣扎,并阅读了无数关于 AJAX、延迟、承诺等的 SO 帖子。
每次,随着我所做的每一次更改,它仍然是相同的:在所有 AJAX 调用完成之前调用 generateLSRDetailRadiusMetrics 函数。 :-(

这是我想要做的:

循环遍历一个数组,对于数组中的每个项目,我需要调用两 (2) 个 AJAX 函数。一旦数组中的所有项目都进行了两 (2) 个 AJAX 调用,然后我需要等待所有待处理的调用完成,然后再继续下一步。

两个 AJAX 调用: promises.push(saveLayerCBG(radiusLayerObject, false)) 和 promises.push(saveLayerPractices(radiusLayerObject, false)) 都返回承诺。如果我破坏了代码,我可以看到该数组确实包含 Promise。

根据我正在阅读的内容(但不是很清楚),我需要将承诺添加到数组中,然后使用 $.when.apply($, promises).done 语法评估 promise 数组。

我在这里做错了什么?

这是我的主要代码:

function LSRRadiusMapProcessing(radiusMaps, newLSR, allRadiusLayers, lsrHeaderId, specialtyId) {
    return new Promise(function (resolve, reject) {
        const options = { steps: 64, units: 'miles' };
        let promises = [];
        for (let i = 0; i < radiusMaps.length; i++) { 
            promises.push(saveLayerCBG(radiusLayerObject, false));
            promises.push(saveLayerPractices(radiusLayerObject, false));
        }

        $.when.apply($, promises).done(function () {
            const lsrdetails = generateLSRDetailRadiusMetrics(lsrHeaderId, specialtyId);
            lsrdetails.then(function () {
                resolve(); 
            });
        });
    });
};

【问题讨论】:

  • 我想你想要Promise.all(promises)
  • @Barmar 而不是 $.when.apply($,promises).done 语句?
  • 是的。虽然我认为$.when.apply($, promises) 应该是等价的。
  • 对...两者之间似乎存在一些细微差别,但并非如此。但是,从 $.when.apply($, promises) 更改为 Promise.all(promises) 并没有奏效。

标签: javascript jquery ajax


【解决方案1】:

jQuery Deferreds to Promises 的“细微”区别如下:

$.when($.get(url1),$.get(url2))
 .then(function(){console.log(arguments[0][0]+arguments[1][0]);})

使用.when(),您可以将多个延迟组合到一个公共组中。下面的 (jQuery-).then() 将处理所有 AJAX 调用的结果。 .then() 中的回调函数应设置为期望与 $.when() 调用中的延迟一样多的参数。在我的示例中,我只是在回调函数中使用 arguments 迭代器来访问所有参数。

// set up AJAX environment for testing:
// mirror data back as a JSON string (works only with GET):
function echoURL(data) {
  return URL.createObjectURL(new Blob([JSON.stringify(data)],{type: "text/json"}));
}
// two "URLS" returning different values (35 and 7)
const url1=echoURL(35), url2=echoURL(7);

//================================
//actual demo of jQuery deferreds:
//================================

$.when($.get(url1),$.get(url2))
 .then(function(){console.log("then:",arguments[0][0]+arguments[1][0]);})
 
 // it works just as well with .done():
 
 $.when($.get(url1),$.get(url2))
 .done(function(){console.log("done:",arguments[0][0]+arguments[1][0]);})
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 感谢您的学习;但是,我不确定它与我的问题/问题有何关系。我对参数不感兴趣,并且我不执行 AJAX 调用作为时间的一部分。 AJAX 调用是在循环中完成的,promise 被聚合到 promises 数组中。
  • 我不得不承认,要处理的代码太多,而我没有时间这样做。;-) 如果你能以某种方式简化你的例子并将其变成一个真正的minimum complete and verifiable example。那么我和这里的其他人会更容易理解你的观点。通过我的回答,我试图表明如果您使用延迟而不是承诺,您可以留在 jQuery 世界中。
猜你喜欢
  • 2017-03-15
  • 2014-07-06
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 2010-10-19
  • 2019-03-03
  • 2012-10-13
  • 1970-01-01
相关资源
最近更新 更多