Implementei $ q.all no angularjs, mas não consigo fazer o código funcionar. Aqui está o meu código:
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);
}
E aqui está meu controlador que chama os serviços:
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
})
Acho que há algum problema ao configurar $ q.all em meu serviço.
then(datas)
? Tente apenaspush
isto:promises.push(deffered);
deferred
nãodeffered
:)Respostas:
Em javascript, não existem
block-level scopes
apenasfunction-level scopes
:Leia este artigo sobre o escopo e levantamento de javaScript .
Veja como depurei seu código:
var deferred= $q.defer();
dentro de um loop for, ele é içado para o topo da função, significa que o javascript declara essa variável no escopo da função fora dofor loop
.closure scope
mesmo após a execução das funções.Solução com
angular.forEach
:Aqui está um plunker de demonstração: http://plnkr.co/edit/NGMp4ycmaCqVOmgohN53?p=preview
Minha maneira favorita é usar
Array#map
:Aqui está um plunker de demonstração: http://plnkr.co/edit/KYeTWUyxJR4mlU77svw9?p=preview
fonte
map
para construir uma série de promessas. Muito simples e conciso.$ http também é uma promessa, você pode torná-la mais simples:
fonte
.then()
cláusula de fora, pois o OP quer fazer tudo isso em seu controlador, mas o princípio está totalmente correto.throw
partir de um.then
para tanto lidar com isso mais tarde quanto para expô-lo$exceptionHandler
, o que deve lhe poupar esse problema e ser global.O problema parece ser que você está adicionando o
deffered.promise
quandodeffered
é a promessa que você deve adicionar:Tente mudar para
promises.push(deffered);
para não adicionar a promessa desembrulhada ao array.fonte
$q.all
recebe promessas e não objetos adiados. O verdadeiro problema do OP é com o escopo e porque apenas o último adiado está sendo resolvidodefer
objetos epromises
. Você consertou meuall()
problema também.