多个 Promise.all - 等待每个(和所有)完成

Multiple Promise.all - wait for each (and all) to finish

我正在尝试按顺序执行多个 Promise.all() 并等待每个 Promise.all() 完成后再继续,然后 return Promise.resolve().

本质上我想要

  1. 首先 - 将数据写入临时位置。
  2. 等待临时写入完成然后 - 将数据移动到位
  3. 等待数据移动到位,然后清理临时数据
  4. 等待以上全部完成再解析

我的代码存在于 Firebase 实时数据库触发器事件中。

我遇到的问题是数据库函数完成得太早,在所有承诺都得到解决之前。为什么函数在所有承诺完成之前完成?

  return Promise.all(firstPromises)
  .then((firstResult) => {
    // Proceed move data from firstPromises to another location
    let movePromises = []
    movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/1`, to:'one'}))
    movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/2`, to:'two'}))
    movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/3`, to:'three'}))
    movePromises = movePromises.concat(myFunc.moveStuff({dbRoot, from:`${tmpPath}/4`, to:'four'}))
    return Promise.all(movePromises)
  }) 
  .then((moveResult) => {
    // Result from Promise.all(movePromises)
    // Clean up
    return Promise.all(cleanPromises)
  })
  .then((cleanResult) => {
    // Result from Promise.all(cleanPromises)
    return Promise.resolve(true)
  })
  .catch((err) => {
    console.error('Error', err)
    // Clean up
    cleanPromises.push(myFunc.cleanup({dbRoot, path:tmpPath}))
    return Promise.all(cleanPromises)
    // return Promise.reject(err)
  })

myFunc.moveStuff():

moveStuff : ({dbRoot, from, to}) => {
  console.log(`moveStuff from '${from}' --> '${to}'`)
  let myPromises = []
  dbRoot.child(from).once('value', (snaps)=>{
    console.log(`${from} to move:`, snaps.numChildren())
    snaps.forEach((node)=>{
      const path = `${to}/${node.key}`
      const nodeData = node.val()
      myPromises.push(
        dbRoot.child(path).set(nodeData)
        .then((writeRes)=> {
          return dbRoot.child(from).remove()
        })
        .then((deleteRes)=>{
          return Promise.resolve(true)
        })
        .catch((e)=>{
          console.error('moveStuff error', e)
          return Promise.reject(e)
        })
      )
    })
  })
  return myPromises
}

这是我的控制台注销:

cleanup my/SYSTEM
moveStuff from '/my-tmp/SYSTEM/1' --> 'one'
moveStuff from '/my-tmp/SYSTEM/2' --> 'two'
moveStuff from '/my-tmp/SYSTEM/3' --> 'three'
moveStuff from '/my-tmp/SYSTEM/4' --> 'four'
Function execution took 3473 ms, finished with status: 'ok'
/my-tmp/SYSTEM/1 to move: 9
/my-tmp/SYSTEM/2 to move: 100
/my-tmp/SYSTEM/3 to move: 0
/my-tmp/SYSTEM/4 to move: 22

亲切的问候/K

我通过使用更多控制台日志和 async/await.

的实施阐明执行过程来解决问题

moveStuff()

moveStuff : async ({dbRoot, from, to}) => {
  let myPromises = []
  await dbRoot.child(from).once('value', (snaps)=>{
    console.log(`moveStuff from '${from}' --> '${to}'`)
    console.log(`${from} to move:`, snaps.numChildren())
    snaps.forEach((node)=>{
      const path = `${to}/${node.key}`
      const nodeData = node.val()
      myPromises.push(
        dbRoot.child(path).set(nodeData)
        .then((writeRes)=> {
          return dbRoot.child(from).remove()
        })
        .then((deleteRes)=>{
          return Promise.resolve(true)
        })
        .catch((e)=>{
          console.error('moveStuff error', e)
          return Promise.reject(e)
        })
      )
    })
  })
  return myPromises
}

承诺链:

  return Promise.all(firstPromises)
  .then((firstResult) => {
    // Proceed move data from firstPromises to another location
    console.log('First finished')
    let movePromises = []
    movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/1`, to:'one'}))
    movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/2`, to:'two'}))
    movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/3`, to:'three'}))
    movePromises = movePromises.concat(await myFunc.moveStuff({dbRoot, from:`${tmpPath}/4`, to:'four'}))
    return Promise.all(movePromises)
  }) 
  .then((moveResult) => {
    // Result from Promise.all(movePromises)
    console.log('Move finished')
    // Clean up
    return Promise.all(cleanPromises)
  })
  .then((cleanResult) => {
    console.log('Clean finished')
    // Result from Promise.all(cleanPromises)
    return Promise.resolve(true)
  })
  .catch((err) => {
    console.error('Error', err)
    // Clean up
    cleanPromises.push(myFunc.cleanup({dbRoot, path:tmpPath}))
    return Promise.all(cleanPromises)
    // return Promise.reject(err)
  })

我的注销现在显示

First finished
Move finished
Clean finished
Function execution took 3473 ms, finished with status: 'ok'