Angular JS 循环承诺
Angular JS Loop Promise
我这里有个情况。我有一个 promise 函数,它 运行 是这样的
我的承诺函数 "getQuestion" 调用另一个承诺函数 DB.query 从 mysqlite 数据库中获取结果 (Main_Question)。
在我得到 DB.query 的结果后,我调用了 getAnswer 函数,它也是一个获取该问题答案的 promise 函数
现在Main_Question可能有N个子题。所以我再次 运行 DB.query 其中获取所有 Sub_Questions。
现在我必须获取这些 Sub_Questions 的答案。显然它只能通过循环来完成。所以我 运行 一个 for 循环遍历 Sub_Question 的每个元素以获得它的答案
现在问题出在第 4 步,循环 运行 很好但没有 return 承诺响应因此我有时会得到每个子问题答案的错误值。
这是我的代码
self.getQuestion = function(questionNumber, sectionId) {
var deferred = $q.defer();
var question = {};
question.hasCounter = false;
question.hasDetail = false;
question.hasSubSection = false;
console.log('SELECT * FROM question WHERE question_type = 1 AND question_number = '+ questionNumber +' AND section_id = ' + sectionId);
DB.query('SELECT * FROM question WHERE question_type = 1 AND question_number = ? AND section_id = ?', [questionNumber, sectionId])
.then(function(result){
console.log(result);
question.main = DB.fetch(result);
console.log(question.main);
Answer.getAnswer(question.main.question_id).then(function(answer) {
question.main.answer = answer;
//Check if this question has any counter question
console.log('SELECT * FROM question WHERE question_type = 2 AND parent_id = ' + question.main.question_id);
DB.query('SELECT * FROM question WHERE question_type = 2 AND parent_id = ?', [question.main.question_id])
.then(function(result){
console.log(result);
if(result.rows.length == 0)
{
question.hasCounter = false;
//Check if this question still has any subsection (s)
console.log('SELECT * FROM question WHERE section_id = '+ sectionId +' AND question_number = '+ question.main.question_number +' AND question_number_section != ""');
DB.query('SELECT * FROM question WHERE section_id = ? AND question_number = ? AND question_number_section != ""', [sectionId, question.main.question_number])
.then(function(result){
if(result.rows.length == 0)
{
question.hasSubSection = false;
deferred.resolve(question);
}
else
{
question.hasSubSection = true;
question.sub = DB.fetchAll(result);
console.log(question.sub);
for (var i in question.sub)
{
console.log("i+"+i);
(function(j)
{
console.log("j+"+j);
question.sub[j].answer = {};
Answer.getAnswer(question.sub[j].question_id).then(function(res) {
question.sub[j].answer = res;
if(j == (question.sub.length-1))
{
deferred.resolve(question);
}
})
})(i);
};
}
});
}
else
{
question.hasCounter = true;
question.counter = DB.fetch(result);
Answer.getAnswer(question.counter.question_id).then(function(answer) {
question.counter.answer = answer;
});
//Get detail question
DB.query('SELECT * FROM question WHERE question_type = 3 AND parent_id = ?', [question.counter.question_id])
.then(function(result){
question.detail = DB.fetchAll(result);
question.hasDetail = true;
for (var j in question.detail)
{
(function(i)
{
question.detail[i].answer = {};
console.log(question.detail[i].question_id);
Answer.getDetailAnswer(question.detail[i].question_id, i).then(function(res) {
console.log(res);
question.detail[i].answer = res;
if(j == (question.detail.length-1))
{
deferred.resolve(question);
}
})
})(j);
};
});
}
});
});
});
return deferred.promise;
};
self.getAnswer = function(questionId) {
var deferred = $q.defer();
DB.query('SELECT * FROM answer WHERE question_id = ?', [questionId])
.then(function(result){
answer = DB.fetch(result);
if(answer && answer.answer_type == 3)
{
deferred.resolve(answer);
}
//Get Answer Option
if(answer)
{
DB.query('SELECT * FROM answer_option WHERE answer_id = ? ORDER BY option_code', [answer.answer_id])
.then(function(result){
answer.answerOptions = DB.fetchAll(result);
deferred.resolve(answer);
});
}
});
return deferred.promise;
};
self.getDetailAnswer = function(questionId, index) {
var deferred = $q.defer();
var answer = [];
DB.query('SELECT * FROM answer WHERE question_id = ?', [questionId])
.then(function(result){
answer[index] = DB.fetch(result);
if(answer[index] && answer[index].answer_type == 3)
{
console.log("Resolved: " + answer[index].answer_id);
deferred.resolve(answer[index]);
}
//Get Answer Option
if(answer[index])
{
DB.query('SELECT * FROM answer_option WHERE answer_id = ? ORDER by option_code', [answer[index].answer_id])
.then(function(result){
//console.log(answer.answer_id + " / " + questionId);
answer[index].answerOptions = DB.fetchAll(result);
deferred.resolve(answer[index]);
console.log("Resolved 2: " + answer[index].answer_id + " / " + questionId);
});
}
});
return deferred.promise;
};
您必须等待所有承诺解决 $q.all()
获取您的子答案应该与此类似(我可能搞砸了带有括号的内容):
var subPromises = [];
for (var i in question.sub)
{
console.log("i+"+i);
(function(j) {
console.log("j+"+j);
question.sub[j].answer = {};
var subPromise = Answer.getAnswer(question.sub[j].question_id).then(function(res) {
question.sub[j].answer = res;
});
subPromises.push(subPromise);
})(i);
}
$q.all(subPromises).then(function() {
deferred.resolve(question);
});
另外,检查一下:Wait for all promises to resolve。
我这里有个情况。我有一个 promise 函数,它 运行 是这样的
我的承诺函数 "getQuestion" 调用另一个承诺函数 DB.query 从 mysqlite 数据库中获取结果 (Main_Question)。
在我得到 DB.query 的结果后,我调用了 getAnswer 函数,它也是一个获取该问题答案的 promise 函数
现在Main_Question可能有N个子题。所以我再次 运行 DB.query 其中获取所有 Sub_Questions。
现在我必须获取这些 Sub_Questions 的答案。显然它只能通过循环来完成。所以我 运行 一个 for 循环遍历 Sub_Question 的每个元素以获得它的答案
现在问题出在第 4 步,循环 运行 很好但没有 return 承诺响应因此我有时会得到每个子问题答案的错误值。
这是我的代码
self.getQuestion = function(questionNumber, sectionId) {
var deferred = $q.defer();
var question = {};
question.hasCounter = false;
question.hasDetail = false;
question.hasSubSection = false;
console.log('SELECT * FROM question WHERE question_type = 1 AND question_number = '+ questionNumber +' AND section_id = ' + sectionId);
DB.query('SELECT * FROM question WHERE question_type = 1 AND question_number = ? AND section_id = ?', [questionNumber, sectionId])
.then(function(result){
console.log(result);
question.main = DB.fetch(result);
console.log(question.main);
Answer.getAnswer(question.main.question_id).then(function(answer) {
question.main.answer = answer;
//Check if this question has any counter question
console.log('SELECT * FROM question WHERE question_type = 2 AND parent_id = ' + question.main.question_id);
DB.query('SELECT * FROM question WHERE question_type = 2 AND parent_id = ?', [question.main.question_id])
.then(function(result){
console.log(result);
if(result.rows.length == 0)
{
question.hasCounter = false;
//Check if this question still has any subsection (s)
console.log('SELECT * FROM question WHERE section_id = '+ sectionId +' AND question_number = '+ question.main.question_number +' AND question_number_section != ""');
DB.query('SELECT * FROM question WHERE section_id = ? AND question_number = ? AND question_number_section != ""', [sectionId, question.main.question_number])
.then(function(result){
if(result.rows.length == 0)
{
question.hasSubSection = false;
deferred.resolve(question);
}
else
{
question.hasSubSection = true;
question.sub = DB.fetchAll(result);
console.log(question.sub);
for (var i in question.sub)
{
console.log("i+"+i);
(function(j)
{
console.log("j+"+j);
question.sub[j].answer = {};
Answer.getAnswer(question.sub[j].question_id).then(function(res) {
question.sub[j].answer = res;
if(j == (question.sub.length-1))
{
deferred.resolve(question);
}
})
})(i);
};
}
});
}
else
{
question.hasCounter = true;
question.counter = DB.fetch(result);
Answer.getAnswer(question.counter.question_id).then(function(answer) {
question.counter.answer = answer;
});
//Get detail question
DB.query('SELECT * FROM question WHERE question_type = 3 AND parent_id = ?', [question.counter.question_id])
.then(function(result){
question.detail = DB.fetchAll(result);
question.hasDetail = true;
for (var j in question.detail)
{
(function(i)
{
question.detail[i].answer = {};
console.log(question.detail[i].question_id);
Answer.getDetailAnswer(question.detail[i].question_id, i).then(function(res) {
console.log(res);
question.detail[i].answer = res;
if(j == (question.detail.length-1))
{
deferred.resolve(question);
}
})
})(j);
};
});
}
});
});
});
return deferred.promise;
};
self.getAnswer = function(questionId) {
var deferred = $q.defer();
DB.query('SELECT * FROM answer WHERE question_id = ?', [questionId])
.then(function(result){
answer = DB.fetch(result);
if(answer && answer.answer_type == 3)
{
deferred.resolve(answer);
}
//Get Answer Option
if(answer)
{
DB.query('SELECT * FROM answer_option WHERE answer_id = ? ORDER BY option_code', [answer.answer_id])
.then(function(result){
answer.answerOptions = DB.fetchAll(result);
deferred.resolve(answer);
});
}
});
return deferred.promise;
};
self.getDetailAnswer = function(questionId, index) {
var deferred = $q.defer();
var answer = [];
DB.query('SELECT * FROM answer WHERE question_id = ?', [questionId])
.then(function(result){
answer[index] = DB.fetch(result);
if(answer[index] && answer[index].answer_type == 3)
{
console.log("Resolved: " + answer[index].answer_id);
deferred.resolve(answer[index]);
}
//Get Answer Option
if(answer[index])
{
DB.query('SELECT * FROM answer_option WHERE answer_id = ? ORDER by option_code', [answer[index].answer_id])
.then(function(result){
//console.log(answer.answer_id + " / " + questionId);
answer[index].answerOptions = DB.fetchAll(result);
deferred.resolve(answer[index]);
console.log("Resolved 2: " + answer[index].answer_id + " / " + questionId);
});
}
});
return deferred.promise;
};
您必须等待所有承诺解决 $q.all()
获取您的子答案应该与此类似(我可能搞砸了带有括号的内容):
var subPromises = [];
for (var i in question.sub)
{
console.log("i+"+i);
(function(j) {
console.log("j+"+j);
question.sub[j].answer = {};
var subPromise = Answer.getAnswer(question.sub[j].question_id).then(function(res) {
question.sub[j].answer = res;
});
subPromises.push(subPromise);
})(i);
}
$q.all(subPromises).then(function() {
deferred.resolve(question);
});
另外,检查一下:Wait for all promises to resolve。