Javascript Firestore承诺在For循环中收集查询(Nuxt.js)
我一直在尝试模拟Firestore中的join语句,通过迭代注释集合将用户加入注释。我知道当您查询集合时,它会返回一个承诺和响应,但是,我不知道如何在响应中迭代文档并在for循环中执行另一个查询 这是一个基本的例子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')
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 }
})
})
}
作为替代方案,您可以使用类似于库的方法来处理来自异步函数的流
希望这有帮助