【问题标题】:Async function not waiting long enough to push firestore docs into an array异步函数没有等待足够长的时间将 firestore 文档推送到数组中
【发布时间】:2021-05-31 09:31:41
【问题描述】:

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

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

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

  • 这不是 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)
  }


}

【问题讨论】:

    标签: javascript arrays google-cloud-firestore async-await


    【解决方案1】:

    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 并使用 Promise.all 等待它们

    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

    【讨论】:

    • 你只是节省了我的一天:) 我正在尝试 forEach() 函数,但我现在意识到使用 for 函数。 agian 非常有用的答案
    猜你喜欢
    • 2019-03-14
    • 2018-12-09
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 2020-08-25
    • 1970-01-01
    • 2014-07-04
    • 1970-01-01
    相关资源
    最近更新 更多