使用顺序/依赖操作的嵌套Q应答
模糊标题的道歉 - 我想不出一种简洁地总结这个问题的方法。使用顺序/依赖操作的嵌套Q应答
这是交易。我有了做一些连续的数据库操作的节点控制器,会是这样的:
0. Given a surveyId 1. Find all entries in the question table, where question.surveyId = surveyId.
2. For each row in the question table returned by the previous query:
a) Find all entries in the `answer` table, where answer.questionId = question.id
b) For each row in the answer table returned by the previous query:
(i) Find the count of all entries in the vote table where vote.answerId = answer.id
控制器需要返回包含的次数的计数的对象有在投票表中的条目每个answerId。它看起来像{1:9, 2:21, 3:0}
,其中1,2,3是回答ID,9,21和0是投票表中具有该回答ID的行数的计数。
我一直在使用Q库来避免真正深度嵌套的回调。我有一个runQuery实用程序方法,它返回一个promise并在数据库IO完成时解析它。
现在,我有东西,看起来像:
runQuery("find questions with surveyid matching given surveyid") .then({
"for each question row returned by query:"
runQuery("find answers with questionid matching this question row")
.then({
"for each answer row returned by query:"
runQuery("find votes with answerID matching this answer row")
.then({
"for each vote row"
"increment the count for this answerid in the return object"
})
})
})
的问题是,返回的对象始终是空的时,控制器返回,因为还没有足够的时间对所有的数据库OPS来完成和承诺解决(至少,我认为这是问题 - 这显然是很难排除类似这些异步承诺的事情。)
有没有更好的方式做到这一点?我应该放弃Q并处理一堆嵌套回调?
回答:
您不能对异步操作使用常规顺序编程。因此,你不能有下一行顺序代码可以使用的返回对象。
相反,使用返回对象的代码必须从成功处理程序调用或承诺完成最后一个操作。这就是异步编码的工作原理,必须采用这些类型的技术才能正常工作。
因此,在你的伪代码,它看起来像这样(的开头的行**是我加的):
runQuery("find questions with surveyid matching given surveyid") .then({
"for each question row returned by query:"
runQuery("find answers with questionid matching this question row")
.then({
"for each answer row returned by query:"
runQuery("find votes with answerID matching this answer row")
.then({
"for each vote row"
"increment the count for this answerid in the return object"
** call function and pass it the return object
to process the final result
})
})
})
// you cannot put code here that uses the return object because
// the return object is not yet available
回答:
有优点与单个查询这样做。客户端和服务器之间不会有“聊天”,在这种情况下,这将节省大约2次整个网络的往返时间(通常是每秒十分之一秒,大概是眨眼的时间,也就是说,可观的人力时间和长时间无聊的等待机器)。
但是,如果您需要使用Q顺序撰写承诺,则有许多选项。这是一个匹配你的伪代码的形式。把它分解成更小的函数是很好的。
runQuery("find questions with surveyId matching given surveyId") .then(function (questions) {
return Q.all(questions.map(function (question) {
return runQuery("find answers matching question.id")
.then(function (answers) {
question.answers = answers;
return Q.all(answers.map(function (answer) {
return runQuery("find votes for each matching question")
.then(function (votes) {
answer.votes = votes;
return answer;
})
}))
})
.thenResolve(question);
}))
});
这将产生一系列问题的承诺,用相应的答案阵列进行注释,并用他们的投票标注答案。
另请参见https://github.com/kriskowal/q#sequences
以上是 使用顺序/依赖操作的嵌套Q应答 的全部内容, 来源链接: utcz.com/qa/263645.html