javascript – jQuery Deferred / Promises动态数组没有以正确的顺序执行回调

前端之家收集整理的这篇文章主要介绍了javascript – jQuery Deferred / Promises动态数组没有以正确的顺序执行回调前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

感谢任何有关我在这里误解的内容的见解.我的要求如下:

我有一系列的网址.我想同时为每个URL发出一个AJAX请求,并在第一个请求完成后立即调用第一个回调.然后,如果第二个请求完成,请调用该回调,依此类推.

选项1:

  1. for (var i = 0; i < myUrlArray.length; i++) {
  2. $.ajax({
  3. url: myUrlArray[i]
  4. }).done(function(response) {
  5. // Do something with response
  6. });
  7. }

显然这不起作用,因为无法保证响应将以正确的顺序完成.

选项2:

  1. var promises = [];
  2. for (var i = 0; i < myUrlArray.length; i++) {
  3. promises.push($.ajax({
  4. url: myUrlArray[i]
  5. }));
  6. }
  7. $.when.apply($,promises).then(function() {
  8. // Do something with each response
  9. });

这应该有效,但缺点是它会等待所有AJAX请求完成,然后再触发任何回调.

理想情况下,我应该能够在完成后立即调用第一个回调,然后将第二个回调链接到每当收到响应时执行(或者如果已经解决则立即执行),然后是第三个,依此类推.

数组长度是完全可变的,并且在任何给定时间都可以包含任意数量的请求,因此只需对回调链进行硬编码就不是一种选择.

我的尝试:

  1. var promises = [];
  2. for (var i = 0; i < myUrlArray.length; i++) {
  3. promises.push($.ajax({
  4. url: myUrlArray[i] // Add each AJAX Deferred to the promises array
  5. }));
  6. }
  7. (function handleAJAX() {
  8. var promise;
  9. if (promises.length) {
  10. promise = promises.shift(); // Grab the first one in the stack
  11. promise.then(function(response) { // Set up 'done' callback
  12. // Do something with response
  13. if (promises.length) {
  14. handleAJAX(); // Move onto the next one
  15. }
  16. });
  17. }
  18. }());

问题是回调以完全随机的顺序执行!例如,如果我将’home.html’,’page2.html’,’page3.html’添加到数组中,则响应的顺序不一定是’home.html’,’page3 html的”.

我显然从根本上误解了承诺的工作方式.任何帮助感激不尽!

干杯

编辑

好的,现在我更加困惑了.我使用Alnitak’s answer使用一个阵列制作了this JSFiddle,使用JoeFletch’s answer制作了另一个阵列,它们都没有像我期望的那样工作!任何人都可以看到这里发生了什么?

编辑2

搞定了!根据JoeFletch在下面的回答,我对解决方案进行了如下调整:

  1. var i,responseArr = [];
  2. for (i = 0; i < myUrlArray.length; i++) {
  3. responseArr.push('0'); // <-- Add 'unprocessed' flag for each pending request
  4. (function(ii) {
  5. $.ajax({
  6. url: myUrlArray[ii]
  7. }).done(function(response) {
  8. responseArr[ii] = response; // <-- Store response in array
  9. }).fail(function(xhr,status,error) {
  10. responseArr[ii] = 'ERROR';
  11. }).always(function(response) {
  12. for (var iii = 0; iii < responseArr.length; iii++) { // <-- Loop through entire response array from the beginning
  13. if (responseArr[iii] === '0') {
  14. return; // As soon as we hit an 'unprocessed' request,exit loop
  15. }
  16. else if (responseArr[iii] !== 'done') {
  17. $('#target').append(responseArr[iii]); // <-- Do actual callback DOM append stuff
  18. responseArr[iii] = 'done'; // <-- Set 'complete' flag for this request
  19. }
  20. }
  21. });
  22. }(i)); // <-- pass current value of i into closure to encapsulate
  23. }

TL; DR:我不理解jQuery的承诺,让它在没有它们的情况下工作.

猜你在找的jQuery相关文章