Chaining promise and defered with a for loop in an

2019-08-18 15:37发布

问题:

I try to use promise and defered in an angular application.

I use two functions $scope.checkQuestions() and $scope.saveExerciseApi() but the problem is that the second one is launched before the first has finished wich is not what I had expected.

The first one call promises to update each questions (with a REST service) and then update $scope.formQuestion[] array which is used in a form on the page.

$scope.Questions and $scope.Exercises are already promise object to update and create entities in a REST service.

$scope.formQuestion, $scope.formexercise, $scope.exercises are data used on the webpage.

$scope.checkQuestions = function(){
deferred = $q.defer()
for (i in $scope.formQuestion){
    if ($scope.formQuestion[i].pk == null){     //Save
        $scope.Questions.add($scope.formQuestion[i]).then(function(newquestion){
            deferred.resolve(newquestion);
            $scope.formQuestion[i] = newquestion;
            });
        }    
    }
return deferred.promise;
}

$scope.saveExerciseApi = function() {
    if ($scope.formexercise.pk == null){        //Save
        $scope.Exercises.add($scope.formexercise).then(function(newexercise){
            $scope.exercises.push(newexercise);
            $scope.showform = false;
            });
        }
}

$scope.saveExercise = function() {
    $scope.checkQuestions().then($scope.saveExerciseApi);
}

EDIT:

The following change doesn't fix the problem.

1) $scope.formexercise.questions is still empty and

2) $scope.saveExerciseApi launch never occured

Is there anything wrong in the following logic ? Is there a better and cleaner way to loop over and update local data for questions and after to update exercise data ?

$scope.checkQuestions = function(){
    deferred = $q.defer()
    $scope.formexercise.questions = Array ();
    for (i in $scope.formQuestion){                 
            if ($scope.formQuestion[i].pk == null){
            $scope.Questions.add($scope.formQuestion[i]).then(function(newquestion){
                $scope.formQuestion[i] = newquestion;
                $scope.formexercise.questions.push($scope.formQuestion[i].pk);
                if ($scope.formQuestion.length == i+1){
                deferred.resolve(newquestion);
                }
            });
          } else {
            $scope.Questions.edit($scope.formQuestion[i].pk, $scope.formQuestion[i]).then(function(updatequestion){
            $scope.formexercise.questions.push($scope.formQuestion[i].pk);
            if ($scope.formQuestion.length == i+1){
               deferred.resolve(udpatequestion);
            }
         });
        }
       }
return deferred.promise;
}

回答1:

You resolve method is called as soon first question is saved. The resolve method should be called after adding all new question i believe

$scope.checkQuestions = function(){
deferred = $q.defer()
var questionsToSave=0;
for (i in $scope.formQuestion){
    if ($scope.formQuestion[i].pk == null){     //Save
        int questionsToSave=questionsToSave + 1;
        $scope.Questions.add($scope.formQuestion[i]).then(function(newquestion){
            $scope.formQuestion[i] = newquestion;
            if(questionsToSave<=1)
               deferred.resolve(newquestion);
            else
               questionsToSave=questionsToSave-1;
            });
        }    
    }
return deferred.promise;
}