Javascript Firestore承诺在For循环中收集查询(Nuxt.js)

Javascript Firestore承诺在For循环中收集查询(Nuxt.js),javascript,firebase,vue.js,promise,google-cloud-firestore,Javascript,Firebase,Vue.js,Promise,Google Cloud Firestore,我一直在尝试模拟Firestore中的join语句,通过迭代注释集合将用户加入注释。我知道当您查询集合时,它会返回一个承诺和响应,但是,我不知道如何在响应中迭代文档并在for循环中执行另一个查询 这是一个基本的例子 asyncData ({ params }) { var postRef = Firestore.collection('posts').doc(params.post); var commentRef = Firestore.collection('posts')

我一直在尝试模拟Firestore中的join语句,通过迭代注释集合将用户加入注释。我知道当您查询集合时,它会返回一个承诺和响应,但是,我不知道如何在响应中迭代文档并在for循环中执行另一个查询

这是一个基本的例子

asyncData ({ params }) {
  var postRef = Firestore.collection('posts').doc(params.post);
  var commentRef = 
    Firestore.collection('posts').doc(params.post).collection('comments');
    return commentRef.orderBy('created_on', 'desc').get().then(snapshot => {
        var comments = []
        snapshot.forEach(doc => {
            var docData = doc.data()
            comments.push({
                comment: { data: doc.data(), id: doc.id }
            })
        })
        return comments
    })
    .then(data => {
        var comments = []
        for(const comment of data) {
            Firestore.collection('users-public').doc(comment.comment.data.created_by).get()
            .then(doc => {
                console.log('Got the User!')
                comments.push( {
                    comment: { data: comment.comment.data, id: comment.comment.id },
                    user: doc.data()
                })
            })
        }
        console.log("Returning!")
        return {comments: comments}
    })
},

运行时,it控制台会在“获取用户!”之前记录“Returning!”,因为它们是异步调用。我试着用…的,但没用。有没有办法防止这种情况,并在返回之前等待所有异步调用完成?关键是我可以解析对用户集合和call.data()的承诺调用,否则会出现循环到json的错误。

尝试将所有承诺存储在一个数组中,然后对其调用该方法。这就像一组承诺的包装器,在所有承诺都执行后立即执行回调

如果您喜欢这种方法,您的代码将如下所示:

asyncData({ params }) {
    var postRef = Firestore.collection('posts').doc(params.post);
    var commentRef =
        Firestore.collection('posts').doc(params.post).collection('comments');
    return commentRef.orderBy('created_on', 'desc').get().then(snapshot => {
        var comments = []
        snapshot.forEach(doc => {
            var docData = doc.data()
            comments.push({
                comment: { data: doc.data(), id: doc.id }
            })
        })
        return comments
    })
        .then(data => {
            var comments = []
            // Declare an empty array, where we'll store all the promises
            var promises = []
            for (const comment of data) {
                let promise = Firestore.collection('users-public').doc(comment.comment.data.created_by).get()
                // Push the promise to the array
                promises.push(promise)
            }
            // Callback on this method will execute once all promises on array have been resolved
            Promise.all(promises).then(users => {
                console.log("All users fetched!")
                // users is an array with every promise result for every user query
                users.forEach(user => {
                    let userId = result.id
                    // Attach user to every comment owned by him
                    comments.filter(comment => {
                        return comment.comment.data.created_by === userId
                    }).map(comment => {
                        comment.user = user.data()
                    })
                })
                console.log("Returning!")
                return { comments: comments }
            })
        })
}
作为替代方案,您可以使用类似于库的方法来处理来自异步函数的流


希望这有帮助

尝试将所有承诺存储在一个数组中,然后对其调用该方法。这就像一组承诺的包装器,在所有承诺都执行后立即执行回调

如果您喜欢这种方法,您的代码将如下所示:

asyncData({ params }) {
    var postRef = Firestore.collection('posts').doc(params.post);
    var commentRef =
        Firestore.collection('posts').doc(params.post).collection('comments');
    return commentRef.orderBy('created_on', 'desc').get().then(snapshot => {
        var comments = []
        snapshot.forEach(doc => {
            var docData = doc.data()
            comments.push({
                comment: { data: doc.data(), id: doc.id }
            })
        })
        return comments
    })
        .then(data => {
            var comments = []
            // Declare an empty array, where we'll store all the promises
            var promises = []
            for (const comment of data) {
                let promise = Firestore.collection('users-public').doc(comment.comment.data.created_by).get()
                // Push the promise to the array
                promises.push(promise)
            }
            // Callback on this method will execute once all promises on array have been resolved
            Promise.all(promises).then(users => {
                console.log("All users fetched!")
                // users is an array with every promise result for every user query
                users.forEach(user => {
                    let userId = result.id
                    // Attach user to every comment owned by him
                    comments.filter(comment => {
                        return comment.comment.data.created_by === userId
                    }).map(comment => {
                        comment.user = user.data()
                    })
                })
                console.log("Returning!")
                return { comments: comments }
            })
        })
}
作为替代方案,您可以使用类似于库的方法来处理来自异步函数的流

希望这有帮助