【问题标题】:What is the right way to chain these nested promises?链接这些嵌套承诺的正确方法是什么?
【发布时间】:2020-09-05 05:52:35
【问题描述】:

我正在我的应用程序中执行多个数据库查询。首先是:

var promise1 = fetchDataWithLatParam()
var promise2 = fetchDataWithLngParam()

return Promise.all([promise1, promise2]).then((results) => {
          var items1 = results[0].data()
          var items2 = results[1].data()

          var intersection = items1.filter(a => items2.some(b => a.name === b.name))
          res.send(intersection)
          return intersection
})

在我将引用类型引入数据库之前,这已经足够好了。所以现在我需要在交集查询中做一个额外的事情,我通过使用 item.user = item.user.get() 将 map() 引入到链中。 但这失败了,因为它存储了未解决的承诺,所以我写了一个解决方法,比如:

  var referentialPromises = []
  var intersection = items1
                        .filter(a => items2.some(b => a.name === b.name))
                        .map(item => {
                            referentialPromises.push(item.user.get().then((result) => {
                                 item.user = result.data()
                            })
                        })

  Promise.all(referentialPromises).then(() => {
      res.send(intersection)
      return intersection
  })

如果我关闭发出警告的 lint 检查,即不应该存在嵌套的 Promise,这会起作用。现在我很好奇如何解决这个问题,因为我无法推送到我的生产服务器,因为它具有无法破坏的固定 linting 规则。

【问题讨论】:

  • 我没有看到嵌套的承诺
  • 问题最初不在于嵌套的 Promise。主要问题是在map 中使用push

标签: javascript node.js asynchronous es6-promise


【解决方案1】:

我不确定 linting,但您可以像这样简化代码:

var allThePromises =
  items1
     .filter(a => items2.some(b => a.name === b.name))
     .map(item => item.user.get().then((result) => result.data()));

Promise.all(allThePromises).then((results) => {
 // ... do something with the results
})

【讨论】:

    【解决方案2】:

    你为什么不试试async/await?它可以帮助您避免这些 Promise-hell 问题。

    var promise1 = fetchDataWithLatParam()
    var promise2 = fetchDataWithLngParam()
    
    var results = await Promise.all([promise1, promise2])
    var items1 = results[0].data()
    var items2 = results[1].data()
    
    var referentialPromises = items1
        .filter(a => items2.some(b => a.name === b.name))
        .map(item => {
            return item.user.get().then((result) => {
                item.user = result.data()
            })
        }) 
    
    var intersection = await Promise.all(referentialPromises)
    res.send(intersection)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-26
      • 1970-01-01
      • 2017-10-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-01
      • 2017-03-25
      相关资源
      最近更新 更多