дождитесь асинхронных http-запросов, прежде чем продолжить angular

У меня есть группы задач, у этих групп есть задачи. Вы можете не только добавить существующие задачи в группу, но и создать новые. Эти новые еще не имеют _id в моем mongoDB, поэтому я должен сделать их сначала, прежде чем сделать мой вызов createTaskGroup.

Когда я вызываю createTaskGroup, я петлю через задачи, когда нет _id, я вызываю «addnewtask». Проблема в том, что последняя функция «apiFactory».createTaskGroup » вызывается перед выполнением цикла для выполнения несуществующих задач.

Как дождаться завершения этих функций перед выполнением createTaskGroup?

 dvm.createTaskGroup = function (){
        for (var i = 0; i < dvm.taskgroup.tasks.length; i++) {
            if (angular.isUndefined(dvm.taskgroup.tasks[i]._id)) {

                apiFactory.addNewTask(dvm.taskgroup.tasks[i].description, function (response) {
                    dvm.taskgroup.tasks[i] = response;
                });
            }
        }

            apiFactory.createTaskGroup(dvm.taskgroup, function (response) {
                $mdDialog.hide(dvm.taskgroup);
            })

    };

Я также пытался использовать обещания, обычно я использую обратные вызовы, но я прочитал о $q.все. Так что я бы попробовал. Но тогда я могу жаловаться на Корс, даже это тот же вызов, что и раньше, но с использованием обещания.

dvm.createTaskGroup = function (){
        var callsToWaitForBeforeContinue = [];

        var tempArrayWithTasksWithId = [];

        angular.forEach(dvm.taskgroup.tasks, function(task){
            if(angular.isUndefined(task._id)){
                callsToWaitForBeforeContinue.push(apiFactory.addNewTaskWithPromise(task.description));
            }
            else{
                tempArrayWithTasksWithId.push(task);
            }
        });

        $q.all(callsToWaitForBeforeContinue).then(function(req){
            dvm.taskgroup.tasks = tempArrayWithTasksWithId;

            angular.forEach(req, function(singlePromise){
                dvm.taskgroup.tasks.push(singlePromise);
            });
        });
            apiFactory.createTaskGroup(dvm.taskgroup, function (response) {
                $mdDialog.hide(dvm.taskgroup);
            });

    };

Вот сам http-пост.

 var addNewTaskWithPromise = function(taskDescription){
            var q = $q.defer();

            $http.post(ENV.api + 'tasks/', taskDescription).then(function(response){
              q.resolve(response); 
            }, errorCallback);

            return q.promise;
        };

2 ответа

  1. Вы должны быть в состоянии просто позвонить, как так:

    apiFactory.addNewTaskWithPromise(task.description).then(function(response){
        dvm.taskgroup.tasks[i] = response;
        apiFactory.createTaskGroup(dvm.taskgroup).then(function (response2) {
            $mdDialog.hide(dvm.taskgroup);
        });
    });
    
  2. у меня получилось. Я возвращаю свой http-вызов как обещание, вместо того, чтобы сделать переменную для него

        var addNewTaskWithPromise = function(taskDescription) {
            return $http.post(ENV.api + 'tasks', {
                "description": taskDescription
            });
        };
    

    Вызовите функцию «createtaskgroup» в операторе «then» my $q.все. Не могу объяснить детали, почему это работает сейчас, без переменной temp для моего обещания, я не получил ошибку CORS, вероятно, кто-то здесь, который мог бы объяснить, почему.

    dvm.createTaskGroup = function() {
            var callsToWaitForBeforeContinue = [];
    
            var tempArrayWithTasksWithId = [];
    
            angular.forEach(dvm.taskgroup.tasks, function(task) {
                if (angular.isUndefined(task._id)) {
                    callsToWaitForBeforeContinue.push(apiFactory.addNewTaskWithPromise(task.description));
                } else if(angular.isDefined(task._id)) {
                    tempArrayWithTasksWithId.push(task);
                }
            });
    
            $q.all(callsToWaitForBeforeContinue).then(function(req) {
                dvm.taskgroup.tasks = tempArrayWithTasksWithId;
    
                angular.forEach(req, function(singlePromise) {
                    dvm.taskgroup.tasks.push(singlePromise.data.task);
                });
    
                apiFactory.createTaskGroup(dvm.taskgroup, function(response) {
                    $mdDialog.hide(dvm.taskgroup);
                });
            });
    
        };