javascript - 正确使用 async 和 wait

标签 javascript typescript asynchronous promise

下面的函数在 for 循环中调用多个异步函数。它解析不同的 CSV 文件来构建单个 JavaScript 对象。我想在 for 循环完成后返回该对象。它在执行异步任务时立即返回空对象。有道理,但是我尝试了各种 Promise/async/await 组合,希望在 for 循环完成后运行某些内容。我显然不明白发生了什么事。对于这样的事情是否有更好的模式可以遵循,或者我是否错误地思考了它?

async function createFormConfig(files: string[]): Promise<object>

  return new Promise(resolve => {

    const retConfig: any = {};


    for (const file of files) {


      file.match(matchFilesForFormConfigMap.get('FIELD')) ?
        parseCsv(file).then(parsedData => {
          retConfig.fields = parsedData.data;
        })

        : file.match(matchFilesForFormConfigMap.get('FORM'))
        ? parseCsv(file).then(parsedData => retConfig.formProperties = parsedData.data[0])

        : file.match(matchFilesForFormConfigMap.get('PDF'))
          ? parseCsv(file).then(parsedData => retConfig.jsPdfProperties = parsedData.data[0])

          : file.match(matchFilesForFormConfigMap.get('META'))
            ? parseCsv(file).then(parsedData => {
              retConfig.name = parsedData.data[0].name;
              retConfig.imgType = parsedData.data[0].imgType;
              // console.log(retConfig);  <- THIS CONSOLE WILL OUTPUT RETCONFIG LOOKING LIKE I WANT IT
            })

            : file.match(matchFilesForFormConfigMap.get('PAGES'))
              ? parseCsv(file).then(parsedData => retConfig.pages = parsedData.data)
              : console.log('there is an extra file: ' + file);

    }

    resolve(retConfig);  // <- THIS RETURNS: {}
  });

这是我用来调用该函数的代码,希望用 CSV 数据填充我的“retConfig”。

getFilesFromDirectory(`${clOptions.directory}/**/*.csv`)
  .then(async (files) => {
    const config = await createFormConfig(files);
    console.log(config);
  })
  .catch(err => console.error(err));

};

最佳答案

首先,async 函数返回一个 Promise,因此您不必显式返回一个。以下是简化代码的方法:

async function createFormConfig(files: string[]): Promise<object> {

  // return new Promise(resolve => { <-- remove

  const retConfig: any = {};

  // ...

  // The value returned by an async function is the one you get
  // in the callback passed to the function `.then` 
  return retConfig;

  // }); <-- remove
}

然后,您的函数 createFormConfig 在完成计算之前返回配置。以下是在返回之前计算它的方法:

async function createFormConfig(files: string[]): Promise<object> {

  const retConfig: any = {};

  // Return a Promise for each file that have to be parsed
  const parsingCsv = files.map(async file => {
    if (file.match(matchFilesForFormConfigMap.get('FIELD'))) {
      const { data } = await parseCsv(file);
      retConfig.fields = data;
    } else if (file.match(matchFilesForFormConfigMap.get('FORM'))) {
      const { data } = await parseCsv(file);
      retConfig.formProperties = data[0];
    } else if (file.match(matchFilesForFormConfigMap.get('PDF'))) {
      const { data } = await parseCsv(file);
      retConfig.jsPdfProperties = data[0];
    } else if (file.match(matchFilesForFormConfigMap.get('META'))) {
      const { data } = await parseCsv(file);
      retConfig.name = data[0].name;
      retConfig.imgType = data[0].imgType;
    } else if (file.match(matchFilesForFormConfigMap.get('PAGES'))) {
      const { data } = await parseCsv(file);
      retConfig.pages = data;
    } else {
      console.log('there is an extra file: ' + file);
    }
  });

  // Wait for the Promises to resolve
  await Promise.all(parsingCsv)

  return retConfig;
}

关于javascript - 正确使用 async 和 wait,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53898288/

相关文章:

typescript - 样式组件 defaultProps

javascript - Promise.all 可以接受所有非 Promise 元素的数组吗?

javascript - 在 Javascript 中编写异步方法(代码在 Node.js 中运行)

javascript - 如何将 Kendo ListView 放入 Kendo PanelBar 的内容中?

javascript - 将 Grails GSP 自定义标记转换为 AngularJS 指令

javascript - 各种迭代器性能差异的原因

grails - Grails异步 promise

javascript - 有哪些工具可用于代码比较或并排比较?如何查找 Javascript 中的错误?

javascript - 如何防止复合组件重新渲染?

c# - 异步/等待内存缓存的线程安全