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

时间:2020-07-16 12:38:20

标签: javascript firebase-realtime-database es6-promise

我尝试依次执行多个Promise.all(),并等待每个Promise.all()完成之后再继续操作,然后返回Promise.resolve()

本质上我想

  1. 首先-将数据写入一个临时位置。
  2. 等待临时写入完成,然后-将数据移到适当位置
  3. 等待数据移入位置,然后-清理临时数据
  4. 等待以上所有内容完成后再解决

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

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

  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

1 个答案:

答案 0 :(得分:0)

我通过澄清更多控制台日志和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'