异步forEach循环返回数组

时间:2020-06-23 15:02:39

标签: javascript node.js asynchronous async-await

我在异步循环中苦苦挣扎,这是我尝试过的:

let array = [];      
  raw.forEach(async element => {
      var elt = new Elt(raw);
      elt.options = await this.getOptions(raw["id"]);
      array.push(elt);
  });
  return array; // this is empty...

我如何“等待它完成”以使数组不为空? 非常感谢!

3 个答案:

答案 0 :(得分:1)

您的第一个问题:输出数组为空,因为您在之前使用了它,否则将执行任何promise。您必须先await使用所有诺言。

第二个问题:承诺可以执行,因此push项可以按(伪)随机顺序执行。您的输出数组可能会被拖曳。

解决方案是(1)await所有诺言和(2)保持它们的顺序(使用Array.prototype.map):

async function foo(input) {
    let output = await Promise.all(input.map(async element => {
        return element * 2;
    }));

    return output;
}

// Call it
let input = [ 1, 2, 3, 4, ]; // This is your input array
foo(input).then(output => console.log(output));

Promises.allasync函数,它接受承诺数组并返回其结果数组。

Array.prototype.map为数组的每个项目执行功能。

更多信息:

答案 1 :(得分:1)

您可以将map和Promise.all用于您的方案

  const promises = raw.map(async element => {
    var elt = new Elt(element )
    elt.options = await this.getOptions(element ["id"])
    return elt
  })
  
  const yourArray = await Promise.all(promises);

答案 2 :(得分:1)

首先等待使用mapPromise.all完成所有选项的异步提取,然后将这些ID映射到元素列表,如下所示:

const options = await Promise.all(raw.map(r => this.getOptions(r.id)));

const elements = options.map(option => {
    const elt = new Elt();
    elt.options = option;
    return elt;
});