首页 > 解决方案 > 异步函数没有等待足够长的时间将 firestore 文档推送到数组中

问题描述

我正在尝试从 Firestore 获取一堆(10-1500)文件,然后一旦我拥有它们,我会检查我得到的数量,然后从那里处理它。

只有当我在抓取文档和检查数组之间有一个手动的“setTimeout”时,我才能让它工作。

在我检查它们之前,该数组没有被所有的 Firestore 文档填充,但它在一个异步函数中,所以我对它为什么不等待感到困惑。

火库

javascript异步函数

async function query(units, days){

  try {

    let allLogs = []

    var ts = moment().subtract(days,'days').valueOf() //ms timestamp from 1 -3 days ago


       await units.forEach(async(e) => {

         let ref = db.collection('units').doc(`${e.unit.superId}`).collection('logs').where('info.ms', '>=', parseInt(ts))

         let docs = await ref.get()  // get all subcollection documents from parent document

          await docs.forEach(async(doc) =>{ // Loop through and push all documents to allLogs array

             allLogs.push(doc.data())

           })
       })


     //If i dont add this: it will always think allLogs is empty. Not waiting long enough for it to be filled

     await new Promise(resolve => setTimeout(resolve, (days+ 1.5) * 1000 )); // x seconds wait for array to be filled


     if (allLogs.length > 0){
       console.log('filled')
     } else {
      console.log('empty')

     }


  } catch(err) {

    console.log(err)
  }


}

标签: javascriptarraysgoogle-cloud-firestoreasync-await

解决方案


forEach 不等待回调

它按顺序触发所有调用并且不等待它们(它也返回未定义,所以等待它什么都不做)

使用 for ... of 循环等待每个调用

for (const unit of units) {
    let ref = db.collection('units').doc(`${unit.unit.superId}`).collection('logs').where('info.ms', '>=', parseInt(ts))
    let docs = await ref.get() // get all subcollection documents from parent document
    docs.forEach((doc) => { // Loop through and push all documents to allLogs array
        allLogs.push(doc.data())
    }
}

或者使用 Promise.all 触发所有的 Promise 并等待所有的 Promise

await Promise.all(units.map(async (unit) => {
    let ref = db.collection('units').doc(`${unit.unit.superId}`).collection('logs').where('info.ms', '>=', parseInt(ts))
    let docs = await ref.get()  // get all subcollection documents from parent document
    docs.forEach((doc) => { // Loop through and push all documents to allLogs array
        allLogs.push(doc.data())
    })
}))

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements /for ... of https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all


推荐阅读