首页 > 解决方案 > How to wait for an ajax call to finish before moving on to the next?

问题描述

I have a situation where I need to make multiple ajax requests. The URLs that I need to access are contained as strings in the listOfUrls array.

What I'd like to do is make one ajax request, process it, feed the data back into my application, and then move onto the next one.

A basic version of the code I've got at the minute is this

var fetch = function(url) {
  $.get(url, function(response) {
    // do stuff with the data
  };
  return someData;
};

for(let i = 0; i < listOfUrls.length; i++) {
  fetch(listOfUrls[i]);
  console.log("Fetching " + listOfUrls);
};

// do more stuff after all requests are finished

The issue here is that these are asynchronous requests, and while I could potentially just use synchronous requests I don't really want to risk that - and then I wouldn't be able to use the console.log within the loop, because the browser would hang.

What I'd prefer to do is use a promise to iterate through the loop:

var fetch = function(url) {
  $.get(url, function(response) {
    // do stuff with the data
  };
  return someData;
};

for(let i = 0; i < listOfUrls.length; i++) {
  fetch(listOfUrls[i]).done( /* move onto the next one */ ).fail( /* throw an error */ );
  console.log("Fetching " + listOfUrls);
};

// do more stuff after all requests are finished

Promises obviously can't force an iteration through the for loop.

How would I go about implementing this behaviour?

标签: jqueryajaxpromise

解决方案


您可以在成功完成前一个 URL 时使用递归调用下一个 URL。

如果我希望 fetch() 也将数据返回到调用它的脚本部分,我该怎么做?

由于所有请求都是异步的,因此您无法返回任何内容。要执行您需要的操作,您可以使用从所有请求中检索到的数据填充一个数组,然后将其提供给您在所有请求完成时调用的另一个函数,如下所示:

var obj = [];

function makeRequest(index) {
  $.get(listOfUrls[index || 0], function(response) {
    // do stuff with the response
    obj.push(response);

    if (++index < listOfUrls.length) {
      makeRequest(index);
    } else {
      finaliseRequests(obj);
    }
  });
}

function finaliseRequests(data) {
  // work with all the received data here...
}

makeRequest(); // onload

推荐阅读