当前位置: 首页 > 知识库问答 >
问题:

正确使用async并等待

倪德业
2023-03-14

下面的函数在for循环中调用几个异步函数。它解析不同的CSV文件来构建单个JavaScript对象。我想在for循环完成后返回对象。它在执行异步任务时立即返回空对象。有道理,但是我尝试了各种Promise/异步 /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));

};

共有2个答案

祁修平
2023-03-14

异步函数已经返回promise,您不需要将代码包装成新的。只要从函数返回一个值,调用者就会收到一个解析为返回值的promise。

此外,您已经创建了一个异步函数,但实际上并没有在任何地方使用wait。因此,在您的任何promise解决之前,for循环将贯穿整个循环。这就是为什么没有数据进入您的对象。

它将真正简化您的代码,只使用wait,并摆脱then()调用。例如,您可以这样做:

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

  const retConfig: any = {};

  for (const file of files) {

    if (file.match(matchFilesForFormConfigMap.get('FIELD')){
      // no need for the then here
      let parsedData = await parseCsv(file)
      retConfig.field = parsedData.data
    }

   // ...etc

最后,您只需返回以下值:

return retConfig
云新知
2023-03-14

首先,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;
}
 类似资料:
  • 本文向大家介绍Array.filter中如何正确使用Async,包括了Array.filter中如何正确使用Async的使用技巧和注意事项,需要的朋友参考一下 1. 如何仅保留满足异步条件的元素 在第一篇文章中,我们介绍了 async / await 如何帮助处理异步事件,但在异步处理集合时却无济于事。在本文中,我们将研究该filter函数,它可能是支持异步函数的最直观的方法。 2. Array.

  • 问题内容: 我喜欢Typescript等中提供的新功能的平坦性。但是,我不确定我是否必须在块的外部声明要输入的变量以便以后使用,这一点我不确定。像这样: 如果我错了,请纠正我,但是似乎最好的做法是不要在主体中放置多行业务逻辑,因此,我只剩下在块外声明,在块中分配,以及然后使用它。 在这种情况下,最佳做法是什么? 问题答案: 似乎最好的做法是不要在try主体中放置多行业务逻辑 其实我会说是的。通常,

  • 问题内容: 我无法弄清楚/的运作方式。我对此有些了解,但无法使其正常工作。 我知道我可以使用,但是如果这样做,我知道我永远不会理解/ 我只会埋葬这个问题。 目标:调用并返回文件的内容。 每次调用该文件都会增加一次(每页加载)。该文件包含二进制缓冲区的转储,并存储在SSD中。 无论我做什么,都会出现错误或在控制台中。 问题答案: 要使用/,您需要返回承诺的方法。没有包装器,核心API函数就不会这样做

  • 目标 建立一个 lesson5 项目,在其中编写代码。 代码的入口是 app.js,当调用 node app.js 时,它会输出 CNode(https://cnodejs.org/ ) 社区首页的所有主题的标题,链接和第一条评论,以 json 的格式。 注意:与上节课不同,并发连接数需要控制在 5 个。 输出示例: [ { "title": "【公告】发招聘帖的同学留意一下这里",

  • 我找到了Polly包,它被设置为在C#中处理try/catch重试。我目前的代码设置如下: 我的方法只是在主线程的当前页面上显示一个: 当我调试这个并切断我的internet连接时。从不显示。发生两件事之一: null 更新: 在将对的调用放到方法中之后,我现在找到了绕过的方法。然而,现在我又有了一个问题。 一旦我断开与internet的连接,就会像应该的那样弹出。程序在完成函数之前等待我单击重试

  • 问题内容: 在我的程序中,我从另一个API模块调用了我的函数: 模块代码: 执行立即返回,但是,并因此包含请求对象和请求体- 样,不需要响应体。 我做错了什么?怎么修?正确的用法是什么,或仅与此处提到的Promise一起正确使用:为什么await对于节点请求模块不起作用?以下文章提到了可能的方法:在Node.js中掌握Async Await 。 问题答案: 您需要使用模块,而不是模块或。 对返回p