【问题标题】:Second layer nested promise第二层嵌套承诺
【发布时间】:2021-08-21 23:49:13
【问题描述】:

我有一个高级 Mongo 查询。

我尝试计算多个字段的不同值。

首先我必须遍历三个值,它们是我的 Mongoose 架构中的条目,然后我必须计算每个相应字段的每个不同值,并将它们作为字符串返回。


const mappedStuff = this.featureFields.map(async field => {
      return new Promise(async (resolve, reject) => {
        const distinctValues = await this.gameModel.distinct(field);
        return distinctValues.map(async entry => {
          console.log(
            `${field}, ${entry},  ${await this.gameModel.count({
              [field]: entry,
            })}`,
          ); //Logs out correct value 
          resolve(
            `${field}, ${entry},  ${await this.gameModel.count({
              [field]: entry,
            })}` as string, //resolves instantly and does not return the correct value
          );
        });
      });
    });
    console.log(Promise.all(mappedStuff));
    return Promise.all(mappedStuff);

console.log 工作正常,我只想返回该值,我尝试将其推送到外部列表,但不起作用,因为我在字符串中有一个 await

因此我尝试将整个事情包装在一个承诺中,但这也不能解决问题。有人有解决办法吗

【问题讨论】:

  • 你想要的输出是什么? Promise.all() 不会在第二层 Promise 中再次使用 Promise.all 来深度等待所有 Promise。此外,在 async 函数中创建新的 Promise 是多余的。

标签: typescript mongodb asynchronous promise


【解决方案1】:

你用 Promise.all() 包裹了外部数组是正确的,但是你忘记对内部数组做同样的事情,你有 distinctValues.map(//...。此外,直接在外部地图中的 Promise 似乎是多余的。

const mappedStuff = this.featureFieldsMap.map(async (field) => {
  const distinctValues = await this.gameModel.distinct(field);
  return await Promise.all(distinctValues.map(async (entry) => {
    // make life easier by not interpolating the asynchronous result.
    const count = await this.gameModel.count({ [field]: entry });
    return `${field}, ${entry}, ${count}`;
  }));
});
return Promise.all(mappedStuff);

【讨论】:

  • +1,尽管您始终可以从 async 函数中返回 Promise(并且 async 函数无论如何都会返回 Promise),因此您可以避免使用 return await 来支持return。 Promise 实现进行解包。
  • 在异步上下文中返回 Promise 是反模式,但我对此感到非常沮丧!我应该映射 distinctValues 并将结果包装在 map 函数内部的 Promise.all() 中。谢谢@Daniel Gimenez
  • @JeffBowman,所以这使得返回之前的 await 变得多余。与此类似? stackoverflow.com/questions/38708550/…
  • @Ating 正确。外部映射是一个异步 lambda,没有 try/catch,所以 return await Promise.all(...) 可以工作,但并不比 return Promise.all(...) 好。我同意在异步上下文中创建显式 Promise 是一种反模式,因此我同意 Daniel 将其删除,但直接从像 Promise.all 这样的助手返回 Promise 是完全合理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-21
  • 2019-05-22
相关资源
最近更新 更多