【问题标题】:Node.js Use Promise.all For returning asynchronous call?Node.js 使用 Promise.all 来返回异步调用?
【发布时间】:2019-01-05 04:40:43
【问题描述】:

目前,我正在使用云功能来查询帖子。当查询帖子时,我在查询帖子的一些额外更新后为firebase设置了一些更新,例如:

 const getPostsForDate = admin.firestore().collection('posts').where('timeOfDeletion', '<', currentTime)
return getPostsForDate.get().then(snapshot => {
    const updates = {} 
    var counter = 0
    const batch = admin.firestore().batch()
    snapshot.forEach((doc) => {

        var key = doc.id
        admin.database().ref('/convoID/' + key).once('value', (snapshot) => {
            if (snapshot.exists()) {
                const convoIDCollection = snapshot.val()
                for (var child in convoIDCollection) {

                    console.log(child)
                    updates["conversations/" + child] = null
                    updates["messages/"+ child] = null
                    updates["convoID/"+ child] = null
                }
            }
            updates["/convoID/" + key] = null
            updates["/reveals/" + key] = null
            updates["/postDetails/" + key] = null
            const postFireStoreRef = admin.firestore().collection('posts').doc(key)
            const posterRef = admin.firestore().collection('posters').doc(key)
            batch.delete(postFireStoreRef)
            batch.delete(posterRef)
            counter++
         })

    })
    if (counter > 0) {
        console.log("at the deletion")
          return Promise.all[admin.database().ref().update(updates), batch.commit()] 
    }
    else {
        console.log("null")
        return null
    }
})

})

然而,问题是查询 admin.database().ref('convoID/...) 是异步的;因此,更新被发送到空的数据库并且没有任何变化。现在,这个问题的解决方案是 promise,除了实现 promise.all 和所有其他返回没有按预期进行。我试过了

 var promises = []
    snapshot.forEach((doc) => {

        var key = doc.id
        promises.push(admin.database().ref('/convoID/' + key).once('value', (snapshot) => {
            if (snapshot.exists()) {
                const convoIDCollection = snapshot.val()
                for (var child in convoIDCollection) {

                    console.log(child)
                    updates["conversations/" + child] = null
                    updates["messages/"+ child] = null
                    updates["convoID/"+ child] = null
                }
            }
            updates["/convoID/" + key] = null
            updates["/reveals/" + key] = null
            updates["/postDetails/" + key] = null
            const postFireStoreRef = admin.firestore().collection('posts').doc(key)
            const posterRef = admin.firestore().collection('posters').doc(key)
            batch.delete(postFireStoreRef)
            batch.delete(posterRef)
            counter++
         })
        )
    })
promises.all(promises).then(() =>
     if (counter > 0) {
        console.log("at the deletion")
          return Promise.all[admin.database().ref().update(updates), batch.commit()] 
    }
    else {
        console.log("null")
        return null
    }
);

除了我收到错误unexpected token if,Declaration or statement expected 最后通过promises.all() 这是等待异步调用完成的正确方法吗?

【问题讨论】:

  • Promise.all(promises).then(() =&gt; { code here });。您的代码使用promises.all() 而不是Promise.all(),并且在.then() 处理程序中的函数体周围缺少{}
  • 并且,return Promise.all[] 应该是 return Promise.all()。您真的要求我们帮助您解决所有这些基本语法错误吗?
  • 另外,你确定admin.database().ref().once() 会返回一个承诺吗?
  • @jfriend00 今天我会试试你的第一条评论,我很确定 fatabase 引用确实会返回一个承诺
  • 好吧,从the doc 看来,如果你不向它传递回调,.once() 确实会返回一个承诺。使用 .then() 代替常规回调。

标签: node.js firebase firebase-realtime-database promise google-cloud-firestore


【解决方案1】:

为了结束这个问题,我将尝试总结一下我们在 cmets 中涵盖的内容:

修复箭头函数定义。更改此:

promises.all(promises).then(() => code here)

到这里:

Promise.all(promises).then(() => { code here });

并且,修复 Promise.all() 的调用。 改变这个:

return Promise.all[...] 

到这里:

return Promise.all([...])

而且,admin.database().ref().once() 将返回一个承诺,但前提是您不通过 .once() 进行常规回调。

所以,改变这个:

promises.push(admin.database().ref('/convoID/' + key).once('value', (snapshot) => { ...}));

到这里:

promises.push(admin.database().ref('/convoID/' + key).once('value').then(snapshot => {...}));

而且,如果你改变它的一般结构,它会更简洁一些:

let promises = [];
snapshot.forEach((doc) => {
   promises.push(...)
});
Promise.all(promises).then(...)

到这里:

Promise.all(snapshot.map(doc => {
    return admin.database().ref('/convoID/' + key).once(...).then(...);
})).then(...);

【讨论】:

    猜你喜欢
    • 2017-03-20
    • 2020-06-04
    • 2015-12-01
    • 2019-07-24
    • 2012-08-13
    • 2021-08-25
    • 1970-01-01
    • 2013-12-15
    • 2012-06-03
    相关资源
    最近更新 更多