sourcecode

Angularjs $q.all

codebag 2023. 3. 19. 18:08
반응형

Angularjs $q.all

$q.all을 angularjs로 구현했는데 코드가 작동하지 않습니다.제 코드는 다음과 같습니다.

UploadService.uploadQuestion = function(questions){

        var promises = [];

        for(var i = 0 ; i < questions.length ; i++){

            var deffered  = $q.defer();
            var question  = questions[i]; 

            $http({

                url   : 'upload/question',
                method: 'POST',
                data  : question
            }).
            success(function(data){
                deffered.resolve(data);
            }).
            error(function(error){
                deffered.reject();
            });

            promises.push(deffered.promise);
        }

        return $q.all(promises);
    }

서비스를 호출하는 컨트롤러는 다음과 같습니다.

uploadService.uploadQuestion(questions).then(function(datas){

   //the datas can not be retrieved although the server has responded    
}, 
function(errors){ 
   //errors can not be retrieved also

})

제 서비스에서 $q.all을 설정하는 데 문제가 있는 것 같습니다.

javascript에는 다음 항목만 있습니다.

JavaScript ScopingHoisting에 대한 이 문서를 읽어보십시오.

코드를 디버깅한 방법을 참조하십시오.

var deferred = $q.defer();
deferred.count = i;

console.log(deferred.count); // 0,1,2,3,4,5 --< all deferred objects

// some code

.success(function(data){
   console.log(deferred.count); // 5,5,5,5,5,5 --< only the last deferred object
   deferred.resolve(data);
})
  • 글을 쓸 때var deferred= $q.defer();function의 맨 위에 hoard된 for loop의 경우 javascript가 function scope의 바깥쪽에서 이 변수를 선언하는 것을 의미합니다.for loop.
  • 각 루프에서는 마지막 지연이 이전 루프보다 우선되므로 해당 객체에 대한 참조를 저장할 블록 수준의 스코프는 없습니다.
  • 비동기 콜백(성공/오류)이 호출되면 마지막 지연 객체만 참조되고 해결됩니다.따라서 $q.all은 다른 지연 객체를 대기하기 때문에 해결되지 않습니다.
  • 필요한 것은 반복하는 각 항목에 대해 익명 함수를 만드는 것입니다.
  • 함수에 스코프가 있기 때문에 지연된 객체에 대한 참조는 함수가 실행된 후에도 유지됩니다.
  • #dfsq 코멘트:$http 자체는 약속을 반환하므로 새로운 지연 개체를 수동으로 구성할 필요가 없습니다.

솔루션angular.forEach:

여기 데모 plunker가 있습니다.

UploadService.uploadQuestion = function(questions){

    var promises = [];

    angular.forEach(questions , function(question) {

        var promise = $http({
            url   : 'upload/question',
            method: 'POST',
            data  : question
        });

        promises.push(promise);

    });

    return $q.all(promises);
}

제가 가장 좋아하는 방법은Array#map:

여기 데모 plunker가 있습니다.

UploadService.uploadQuestion = function(questions){

    var promises = questions.map(function(question) {

        return $http({
            url   : 'upload/question',
            method: 'POST',
            data  : question
        });

    });

    return $q.all(promises);
}

$1200도 약속입니다.심플하게 할 수 있습니다.

return $q.all(tasks.map(function(d){
        return $http.post('upload/tasks',d).then(someProcessCallback, onErrorCallback);
    }));

문제가 되는 것은, 이 에러를 추가하는 것 같습니다.deffered.promise언제deffered그 자체가 당신이 추가해야 할 약속입니다.

로 변경해 보겠습니다.promises.push(deffered);그래서 포장되지 않은 약속을 배열에 추가하지 않습니다.

 UploadService.uploadQuestion = function(questions){

            var promises = [];

            for(var i = 0 ; i < questions.length ; i++){

                var deffered  = $q.defer();
                var question  = questions[i]; 

                $http({

                    url   : 'upload/question',
                    method: 'POST',
                    data  : question
                }).
                success(function(data){
                    deffered.resolve(data);
                }).
                error(function(error){
                    deffered.reject();
                });

                promises.push(deffered);
            }

            return $q.all(promises);
        }

언급URL : https://stackoverflow.com/questions/21310964/angularjs-q-all

반응형