简体   繁体   中英

Wait for async calls inside a loop to finish

I know questions similar to this have been asked many times, but some are old and suggest deprecated solutions, some describe a solution but not in the context of a loop, and none of them directly answers my question. I want to know what is the latest and greatest approach to having a piece of code run after another piece of code is done running a bunch of async calls.

Here is the general structure of the code as I have it:

function fetchProperty(input) {
  $.ajax({
    url: 'https://jsonplaceholder.typicode.com/todos/1' + input
  }).done(function(resp){
    return $.parseJSON(resp).title;
  });
}

inputValues = [1, 2];
outputValues = [];

$.each(inputValues, function(index, value){
  outputValues.push(fetchProperty(value));
});

console.log(outputValues); // will return an empty array

Essentially, I want that last line of code to not be executed until after all of the AJAX calls made inside the $.each() are finished. Obviously, I don't want to use async: false because it is deprecated. What is the best practice on how to defer the console.log until after all of the other deferred AJAX calls are done?

Try to use async await, like in the code below. The problem seems to be that the fetch is async but the console log is not so it print before it fetch the data

async function fetchProperty(input) {
  const resp = await $.ajax({
    url: 'http://some.api/' + input + '/foobar'
  });
   return $.parseJSON(resp).someProperty;
}

inputValues = ['this', 'that'];
outputValues = [];

$.each(inputValues, async function(index, value){
  outputValues.push(await fetchProperty(value));
});

console.log(outputValues);

I'm not sure that $.ajax return a thenable (Promise like) object or not. Then I will convert $.ajax to the Promise first, and use await keyword to get the value from the function. I use for...of instead of $.each to this task, because $.each use callback style, then it will hard to make it working with async/await .

function fetchProperty(input) {
  return new Promise((resolve) => { // return a Promise
    $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/' + input
    }).done(function (resp) {
      resolve(resp.title); // resolve here
    });
  });
}

async function main() {
  const inputValues = [1, 2];
  const outputValues = [];

  for (const value of inputValues) {
    outputValues.push(await fetchProperty(value));
  }
  console.log(outputValues); // the values
}

main();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM