Angular JS循环承诺

Angular JS Loop Promise

本文关键字:承诺 循环 JS Angular      更新时间:2023-09-26

我这里有个情况。我有一个承诺函数,它以这样的方式运行

  1. 我的承诺函数"getQuestion"调用另一个承诺函数DB。

  2. 从mysqlite数据库获取结果(Main_Question)
  3. 我得到DB的结果后。查询时,调用getAnswer函数这也是一个promise函数用于获取问题的答案

  4. 现在Main_Question可以有N个子问题。所以我再次运行DB。获取所有Sub_Questions的查询。

  5. 现在我必须获取这些Sub_Questions的答案。显然,它只能通过循环来完成。运行for循环遍历Sub_Question的每个元素得到答案

现在的问题是第4步,循环运行良好,但没有返回承诺响应,因此我有时会得到每个子问题答案的不正确值。

我的代码

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);
});

还有,看看这个:等待所有的承诺解决