Я реализовал $ 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 в моем сервисе возникла проблема.
then(datas)
? Попробуйте вотpush
что:promises.push(deffered);
deferred
не такdeffered
:)Ответы:
В javascript нет
block-level scopes
толькоfunction-level scopes
:Прочтите эту статью о javaScript Scoping and Hoisting .
Посмотрите, как я отлаживал ваш код:
var deferred= $q.defer();
внутри цикла for, он поднимается в верхнюю часть функции, это означает, что javascript объявляет эту переменную в области видимости функции за пределамиfor loop
.closure scope
даже после выполнения функций.Решение с
angular.forEach
:Вот демонстрационный плункер: http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview
Мой любимый способ - использовать
Array#map
:Вот демонстрационный плункер: http://plnkr.co/edit/KYeTWUyxJR4mlU77svw9?p=preview
источник
map
для создания множества обещаний. Очень просто и лаконично.$ http - тоже обещание, вы можете сделать это проще:
источник
.then()
пункт, поскольку OP хочет сделать все это в своем контроллере, но принцип полностью верен.throw
из a.then
, чтобы обработать его позже и открыть для него$exceptionHandler
, что должно избавить вас от этой проблемы и глобального.Проблема, похоже, в том, что вы добавляете
deffered.promise
когдаdeffered
- это само обещание, которое вы должны добавить:Попробуйте изменить значение на,
promises.push(deffered);
чтобы не добавлять развернутое обещание в массив.источник
$q.all
получает обещания, а не отложенные объекты. Настоящая проблема OP - это определение объема, и потому что решается только последний отложенныйdefer
предметов иpromises
. Выall()
тоже исправили мою проблему.