简体   繁体   English

Node.js使用Promise.all用于返回异步调用吗?

[英]Node.js Use Promise.all For returning asynchronous call?

Currently, I am using cloud functions to query for posts. 目前,我正在使用云功能来查询帖子。 When the post is queried for, I set some updates for firebase after querying for some additional update for the post, as such: 当查询帖子时,我在查询帖子的一些其他更新后为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
    }
})

})

The problem is, however, is that the query admin.database().ref('convoID/...) is asynchronous; 但是问题是查询admin.database()。ref('convoID / ...)是异步的; thus, the updates are sent to the database empty and nothing changes. 因此,更新将空发送到数据库,并且没有任何更改。 Now, the solution to this is promises, except implementing the promise.all with all the other returns is not going as expected. 现在,解决这个问题的方法就是promise,除了实现promise。所有其他回报都不如预期。 I have tried 我努力了

 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
    }
);

Except I receive the error unexpected token if , Declaration or statement expected In the end by the promises.all() Is this the correct way to wait for the asynchronous call to finish? 除了我收到错误的unexpected token ifDeclaration or statement expected ,最后是promises.all()这是等待异步调用完成的正确方法吗?

To wrap this question up, I'll attempt to summarize what we covered in comments: 为了解决这个问题,我将尝试总结一下我们在评论中涉及的内容:

Fix arrow function definition. 修复箭头功能定义。 Change this: 更改此:

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

to this: 对此:

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

And, fix calling of Promise.all(). 并且,修复Promise.all()的调用。 Change this: 更改此:

return Promise.all[...] 

to this: 对此:

return Promise.all([...])

And, admin.database().ref().once() will return a promise, but only if you do NOT pass .once() a regular callback. 并且, admin.database().ref().once()将返回一个promise,但.once()是您不传递.once()一个常规回调。

So, change this: 因此,更改此:

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

to this: 对此:

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

And, it's a little cleaner if you change the general structure of this: 而且,如果您更改此代码的一般结构,则会更干净:

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

to this: 对此:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM