等待循环内的异步调用完成

Wait for async calls inside a loop to finish

我知道类似的问题已经被问过很多次,但有些是旧的并建议弃用的解决方案,有些描述了一个解决方案但不是在循环的上下文中,其中 none 直接回答了我的问题问题。我想知道在完成另一段代码 运行 一堆异步调用后,有一段代码 运行 的最新和最好的方法是什么。

这是我所拥有的代码的一般结构:

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

本质上,我希望在 $.each() 内部进行的所有 AJAX 调用完成之前不执行最后一行代码。显然,我不想使用 async: false 因为它已被弃用。关于如何将 console.log 延迟到所有其他延迟的 AJAX 调用完成之后的最佳做法是什么?

尝试使用async await,就像下面的代码一样。 问题似乎是获取是异步的,但控制台日志不是,所以它在获取数据之前打印

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);

我不确定 $.ajax return 是否是一个 thenable(类似 Promise)的对象。然后我会先将 $.ajax 转换为 Promise,然后使用 await 关键字从函数中获取值。我使用 for...of 而不是 $.each 来完成这个任务,因为 $.each 使用 callback 风格,那么很难让它与 async/await.[=19 一起工作=]

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();