如何在 node.js 中为 firestore 构建递归 async/await 函数
How to structure a recursive async/await function for firestore in node.js
我想做什么:
我正在尝试使用递归方法从 firestore(firebase 数据库)检索所有评论及其回复。这是数据的结构:
有什么问题
父异步函数不等待嵌套异步函数完成。
getThread = async (req, res) => {
// Getting comments belonging to thread
const thread_document = await db.doc(`/Threads/${req.params.threadid}`).get()
threadData = thread_document.data()
threadData.threadid = thread_document.id
const comment_query = await db.collection('Comments').where('threadid', '==', threadData.threadid).get()
// Getting replies belonging to comments
for (document of comment_query){
let commentData = await getReplies(document.id)
threadData.comments.push(commentData )
}
return res.json(threadData)
}
//Recursive function to retrieve replies
getReplies = async (id) => {
let comment = await db.doc(`/Comments/${id}`).get()
let commentData = comment.data()
commentData.comment_replies = commentData.replies.map(idx => {
// The parent async function does not wait for the the async function here to finish.
// Placing a await keyword here will raise the error 'await is only valid in async functions and the top level bodies of modules'
return getReplies(idx)
})
console.log(commentData)
return commentData
}
给定以下示例,
由于父异步函数不等待嵌套的异步函数,现在的执行顺序是 A -> B -> a,a 无法映射到 commentData
,评论 A 的 commentData 将最终为空。因此,我想编写程序来执行 A -> a -> B。为此,我想在 getReplies 之前放置一个 await 关键字,例如
return await getReplies(idx)
但它会引发错误,
await is only valid in async functions and the top level bodies of modules.
这令人困惑,因为 getReplies
已经是一个异步函数。我研究了 Whosebug 中的其他解决方案,但无法使递归函数正常工作。任何见解将不胜感激,谢谢。
commentData.comment_replies = commentData.replies.map(idx => {
// ...
return getReplies(idx)
})
此 map 语句将创建一组承诺,但不会等待这些承诺完成。您应该使用 Promise.all 将它们组合成一个承诺,然后等待该承诺以获取评论回复数组:
const promises = commentData.replies.map(idx => {
return getReplies(idx);
});
commentData.comment_replies = await Promise.all(promises);
Which is confusing as getReplies is already a async function.
您收到该错误是因为您所在的函数是 idx => { return getReplies(idx) }
,它不是异步函数。但是无论如何都不能解决你的问题。
我想做什么:
我正在尝试使用递归方法从 firestore(firebase 数据库)检索所有评论及其回复。这是数据的结构:
有什么问题 父异步函数不等待嵌套异步函数完成。
getThread = async (req, res) => {
// Getting comments belonging to thread
const thread_document = await db.doc(`/Threads/${req.params.threadid}`).get()
threadData = thread_document.data()
threadData.threadid = thread_document.id
const comment_query = await db.collection('Comments').where('threadid', '==', threadData.threadid).get()
// Getting replies belonging to comments
for (document of comment_query){
let commentData = await getReplies(document.id)
threadData.comments.push(commentData )
}
return res.json(threadData)
}
//Recursive function to retrieve replies
getReplies = async (id) => {
let comment = await db.doc(`/Comments/${id}`).get()
let commentData = comment.data()
commentData.comment_replies = commentData.replies.map(idx => {
// The parent async function does not wait for the the async function here to finish.
// Placing a await keyword here will raise the error 'await is only valid in async functions and the top level bodies of modules'
return getReplies(idx)
})
console.log(commentData)
return commentData
}
给定以下示例,
由于父异步函数不等待嵌套的异步函数,现在的执行顺序是 A -> B -> a,a 无法映射到 commentData
,评论 A 的 commentData 将最终为空。因此,我想编写程序来执行 A -> a -> B。为此,我想在 getReplies 之前放置一个 await 关键字,例如
return await getReplies(idx)
但它会引发错误,
await is only valid in async functions and the top level bodies of modules.
这令人困惑,因为 getReplies
已经是一个异步函数。我研究了 Whosebug 中的其他解决方案,但无法使递归函数正常工作。任何见解将不胜感激,谢谢。
commentData.comment_replies = commentData.replies.map(idx => {
// ...
return getReplies(idx)
})
此 map 语句将创建一组承诺,但不会等待这些承诺完成。您应该使用 Promise.all 将它们组合成一个承诺,然后等待该承诺以获取评论回复数组:
const promises = commentData.replies.map(idx => {
return getReplies(idx);
});
commentData.comment_replies = await Promise.all(promises);
Which is confusing as getReplies is already a async function.
您收到该错误是因为您所在的函数是 idx => { return getReplies(idx) }
,它不是异步函数。但是无论如何都不能解决你的问题。