【问题标题】:Is there any way to await a .forEach() in JS [duplicate]有什么方法可以在 JS 中等待 .forEach() [重复]
【发布时间】:2020-06-21 11:00:09
【问题描述】:

我正在构建一个应用程序,我需要从文件中获取元数据,我使用 npm 中的“音乐元数据”来执行此操作,但我需要为一组文件获取它。该模块返回承诺,所以我需要等待它们/使用.then(),但是当我使用等待它时它不会等待它,它只是返回一个空对象数组,当我使用.then() 它返回一个元数据不是的对象数组。我只让它与for/in 循环一起工作:

const getMetadata = async (dirPath, fileName) => {
    return new Promise((resolve, reject) => {
        if (typeof dirPath !== "string") {
            reject(new Error("directory path must be given as String!"));
        }
        if (typeof fileName !== "string") {
            reject(new Error("file name must be given as String!"));
        }

        mm
        .parseFile(`${dirPath}/${fileName}`)
        .then(metadata =>
            resolve({ directory: dirPath, fileName: fileName, ...metadata })
        )
        .catch(err => reject(err));
    });
};

let musicMetadata = [];
for (const file in musicFiles) {
    try {
        musicMetadata.push(await getMetadata(directoryPath, musicFiles[file]));
    } catch (err) {
        console.error(err);
    }
}

但是有没有什么方法可以做到更像“函数式编程”,类似于:

const getMetadata = (dirPath: string, fileName: string): Promise => {
  return new Promise((resolve, reject) => {
    mm.parseFile(`${dirPath}/${fileName}`)
      .then(metadata =>
        resolve({ directory: dirPath, file: fileName, ...metadata })
      )
      .catch(err => reject(err));
  });
};

const musicMetadata = await musicFiles.map(async (file: string) => {
  return new Promise((resolve, reject) => {
    getMetadata(directoryPath, file)
      .then(metadata => resolve(metadata))
      .catch(err => reject(err));
  });
});

TIA 的任何回复!

【问题讨论】:

标签: javascript node.js typescript


【解决方案1】:

我发现可以这样做的一种方法是:

const musicMetadata = await Promise.all(
  musicFiles.map(async file => {
    return await getMetadata(directoryPath, file);
  }
);

希望这会有所帮助:)

【讨论】:

    【解决方案2】:

    考虑在你的 Promise 集合上使用 Promise.all。当它们全部完成时,它将通过一系列已解决的承诺来解决。如果单个拒绝,它将返回那个拒绝。

    let doSomeTask = (msecs)=>{
        return new Promise((resolve,reject)=>{
            setTimeout(()=>{return resolve('I waited ' + msecs)}, msecs);
        });
    }
    
    var promises = [
        doSomeTask(2000),
        doSomeTask(1500),
        doSomeTask(3000)
    ];
    
    Promise.all(promises).then((resolved,rejected)=>{
        console.log(resolved); // Array(3) [ "I waited 2000", "I waited 1500", "I waited 3000" ]
    });
    

    【讨论】:

    • 非常感谢我被这个问题困扰了好几天......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    • 2014-10-26
    • 2021-01-06
    • 2017-01-11
    • 2011-01-19
    • 2012-09-18
    相关资源
    最近更新 更多