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

时间:2019-04-09 16:46:51

标签: javascript fs

我有一个名称数组,想遍历每个名​​称,并使用fm-extra使用promise读取与之对应的文件。我如何等待forEach循环结束,以便可以将结果写入json

这是我当前的代码:

const fs = require("fs-extra");
const path = require("path");
const manifest = require("../manifest.json");


manifest.forEach((element, index) => {
    const coinName = `${element.symbol.toLowerCase()}.svg`;
    let svgPath = path.join(__dirname, '..', 'svg', 'color', coinName);

    fs.readFile(svgPath, "utf8")
        .then(result => {
            const pattern = /#([A-Fa-f0-9]{6})/g
            let color = result.match(pattern)
            if (color === null) {
                manifest[index].color = undefined;
                console.log("null")
            } else {
                manifest[index].color = color;
            }
        })
        .catch(e => console.log(coinName + " NOT FOUND"))


});

fs.writeJSON("./manifest.json", manifest);

1 个答案:

答案 0 :(得分:0)

1)将您的forEach更改为map并返回承诺。

2)等待使用Promise.all()的所有诺言

const fs = require("fs-extra");
const path = require("path");
const manifest = require("../manifest.json");

let promises = manifest.map((element, index) => {
  const coinName = `${element.symbol.toLowerCase()}.svg`;
  let svgPath = path.join(__dirname, '..', 'svg', 'color', coinName);

  return fs.readFile(svgPath, "utf8")
      .then(result => {
        const pattern = /#([A-Fa-f0-9]{6})/g
        let color = result.match(pattern)
        if (color === null) {
          manifest[index].color = undefined;
          console.log("null")
        } else {
          manifest[index].color = color;
        }
      })
      .catch(e => console.log(coinName + " NOT FOUND"))
});

Promise.all(promises).then(() =>
    fs.writeJSON("./manifest.json", manifest));

如果有帮助,请使用此方法创建一个更简单的用例

let files = ['a', 'b', 'c', 'd', 'e', 'f'];

let promises = files.map((file, i) =>
    new Promise(resolve => setTimeout(resolve, i * 1000)));

Promise.all(promises).then(() =>
    console.log('promises all resolved, save file now', promises));