angularjs에서 $ q.all을 구현했지만 코드를 작동시킬 수 없습니다. 내 코드는 다음과 같습니다.
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을 설정하는 데 문제가 있다고 생각합니다.
답변
자바 스크립트에는 없습니다 block-level scopes
만 function-level scopes
:
자바 스크립트 범위 지정 및 호이 스팅 에 대한이 기사 읽기 .
코드를 디버깅 한 방법을 확인하세요.
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();
for 루프 내부에 쓸 때 함수의 맨 위에 올려진다 는 것은 자바 스크립트가 .NET Framework 외부의 함수 범위에서이 변수를 선언한다는 것을 의미합니다for loop
.- 각 루프에서 마지막 지연 은 이전 루프를 재정의하며 해당 객체에 대한 참조를 저장할 블록 수준 범위가 없습니다.
- 비동기 콜백 (성공 / 오류)이 호출되면 마지막 지연된 객체 만 참조 하고 해결되므로 $ q.all은 여전히 다른 지연된 객체를 기다리므로 해결되지 않습니다 .
- 필요한 것은 반복하는 각 항목에 대해 익명 함수를 만드는 것입니다.
- 함수에는 범위가 있기 때문에 지연된 개체에 대한 참조는
closure scope
함수가 실행 된 후에도 . - #dfsq가 언급했듯이 : $ http 자체가 promise를 반환하기 때문에 새로운 지연된 객체를 수동으로 구성 할 필요가 없습니다.
솔루션 angular.forEach
:
다음은 데모 플 런커입니다. http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview
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
.
다음은 데모 플 런커입니다. http://plnkr.co/edit/KYeTWUyxJR4mlU77svw9?p=preview
UploadService.uploadQuestion = function(questions){
var promises = questions.map(function(question) {
return $http({
url : 'upload/question',
method: 'POST',
data : question
});
});
return $q.all(promises);
}
답변
$ http도 약속이므로 더 간단하게 만들 수 있습니다.
return $q.all(tasks.map(function(d){
return $http.post('upload/tasks',d).then(someProcessCallback, onErrorCallback);
}));
답변
문제는 추가 해야 할 약속 자체가 deffered.promise
언제 deffered
인지 추가하는 것 같습니다 .
promises.push(deffered);
언 래핑 된 promise를 배열에 추가하지 않도록로 변경해보십시오 .
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);
}