简体   繁体   中英

What is the right way to chain these nested promises?

I'm doing multiple database queries in my app. First is:

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
})

This was working good enough until I introduced a reference-type into the database. So now in the then I need to do an extra in the intersection query which I did by introducing a map() into the chain with item.user = item.user.get() . But that failed since it stored the unresolved promise instead, so I wrote a workaround like:

  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
  })

Which works if I turn off the lint checks that gives a warning ie nested promises shouldn't exist. Now I'm curious as to how to fix this issue coz I cannot push into my production server as it has fixed linting rules that cannot be broken.

I am not sure about the linting, but you can simplify a bit your code like this:

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
})

Why don't you try async/await ? It can help you avoid these Promise-hell problems.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM