【问题标题】:Typescript map not awaiting result [duplicate]打字稿地图不等待结果[重复]
【发布时间】:2021-04-29 15:21:31
【问题描述】:

我正在使用与 TypeOrm 的多对多关系,它需要 Id 来查找文章的子类别。

问题是地图没有等待将结果推送到数组中。

这是我的地图功能与列表和日志:

const subcategories = articleDto.subcategoriesIds.split(',').map(x => +x)
const subcategoriesList = []
    
await subcategories.map(async (subcategoryId) => {
    console.log('start:' + subcategoryId)
    const category = await this.subcategoriesService.getSubcategoryById(subcategoryId);
    console.log('mid:' + subcategoryId)
    await subcategoriesList.push(category);
    console.log('end:' + subcategoryId)
});

console.log('### ' + subcategories);
console.log('### ' + subcategoriesList);

这是日志的输出:

start:2
start:3
### 2,3
### 
mid:2
end:2
mid:3
end:3

我不明白为什么不等待结果,如果您知道如何解决此问题,感谢您的帮助。

编辑:通过在内部使用地图添加Promise.all 解决了这个问题

const subcategories = articleDto.subcategoriesIds.split(',').map(x => +x);

const subcategoriesList = await Promise.all(subcategories.map((subcategoryId) => {
      return new Promise((resolve => {
        this.subcategoriesService.getSubcategoryById(subcategoryId).then(result => {
          resolve(result);
        });
      }))
    }));

【问题讨论】:

  • 请不要使用.map进行简单的迭代。请改用.forEach 或实际循环。
  • .forEach 不是异步的,我会用promises代替map。
  • 重点是不要滥用.map。它不仅仅是一个迭代数据集的工具。它用于执行映射
  • 是的,我明白了,所以解决方案是使用.for 循环,因为.forEach 不是异步的?
  • 如果您想按顺序处理这些请求或触发所有请求,可以使用常规循环,然后使用 Promise.all 一次等待它们。取决于您是要按顺序还是并行处理这些。由于您的请求之间似乎没有依赖关系,Promise.all 似乎是更好的选择。这就是链接的副本显示的内容。

标签: javascript typescript asynchronous async-await nestjs


【解决方案1】:

数组原型方法不会等待,即使它们是异步的。代码仍然以同步方式触发。如果你需要这些等待你可以做

const subcategories = articleDto.subcategoriesIds.split(',').map(x => +x)
const subcategoriesList = []

for (const subCategoryId of subcategories) {
  console.log('start:' + subcategoryId)
  const category = await this.subcategoriesService.getSubcategoryById(subcategoryId);
  console.log('mid:' + subcategoryId)
  await subcategoriesList.push(category);
  console.log('end:' + subcategoryId);
}

console.log('### ' + subcategories);
console.log('### ' + subcategoriesList);

【讨论】:

  • 感谢您的回答,但我尝试在不使用 for 函数的情况下进行开发...难道不能使用 promise 而不是 await 来等待迭代后的所有 promise 吗?
  • 为什么不使用for函数进行开发?从字面上看,到处都有答案说这是如何做你正在寻找的东西?我想如果你真的想避免for循环你可以map它然后await Promise.all(returnedArrayFromSubcategories.map)
  • 我不使用airbnb javascript style guide之后的for循环
  • 有趣。虽然数组函数通常更容易阅读、更简洁,但绝对有时间使用for of 而不是mapevery。这是其中之一。另一个是当性能是你所寻找的。​​span>
  • 是的,你是对的,我只是习惯于遵循许多公司使用的这种风格指南,有时可能是错误的。明天我会更详细地检查for循环!
猜你喜欢
  • 1970-01-01
  • 2016-10-20
  • 1970-01-01
  • 2022-01-22
  • 2019-12-19
  • 1970-01-01
  • 2021-06-01
  • 1970-01-01
  • 2018-03-08
相关资源
最近更新 更多