Estou lendo sobre diferidos e promessas e continuo descobrindo $.when.apply($, someArray)
. Não estou certo do que isso faz exatamente, procurando uma explicação de que uma linha funciona exatamente (não o trecho de código inteiro). Aqui está algum contexto:
var data = [1,2,3,4]; // the ids coming back from serviceA
var processItemsDeferred = [];
for(var i = 0; i < data.length; i++){
processItemsDeferred.push(processItem(data[i]));
}
$.when.apply($, processItemsDeferred).then(everythingDone);
function processItem(data) {
var dfd = $.Deferred();
console.log('called processItem');
//in the real world, this would probably make an AJAX call.
setTimeout(function() { dfd.resolve() }, 2000);
return dfd.promise();
}
function everythingDone(){
console.log('processed all items');
}
javascript
jquery
asynchronous
promise
manafire
fonte
fonte
.done()
pode ser usado no lugar de.then
neste caso, apenas para sua informação_.when
que você não precise usarapply
.apply
: developer.mozilla.org/en-US/docs/JavaScript/Reference/… .Respostas:
.apply
é usado para chamar uma função com uma matriz de argumentos. Ele pega cada elemento na matriz e usa cada um como um parâmetro para a função..apply
também pode alterar o context (this
) dentro de uma função.Então, vamos pegar
$.when
. Costuma-se dizer "quando todas essas promessas forem resolvidas ... faça algo". Leva um número infinito (variável) de parâmetros.No seu caso, você tem uma série de promessas; você não sabe para quantos parâmetros está passando
$.when
. Passar o próprio array para$.when
não funcionaria, porque ele espera que seus parâmetros sejam promessas, não um array.É aí que
.apply
entra. Ele pega a matriz e chama$.when
cada elemento como um parâmetro (e garante quethis
esteja definido comojQuery
/$
), então tudo funciona :-)fonte
$.when
basta esperar que todos eles sejam finalizados antes de continuar.$.when($, arrayOfPromises).done(...)
e$.when(null, arrayOfPromises).done(...)
(que eu encontrei como soluções propostas nos fóruns ...)$ .when pega qualquer número de parâmetros e resolve quando todos eles foram resolvidos.
anyFunction .apply (thisValue, arrayParameters) chama a função anyFunction definindo seu contexto (thisValue será o this dentro da chamada de função) e passa todos os objetos em arrayParameters como parâmetros individuais.
Por exemplo:
É o mesmo que:
Mas a forma de chamar apply permite que você passe uma matriz de um número desconhecido de parâmetros. (Em seu código, você está dizendo que seus dados vêm de um serviço, então essa é a única maneira de chamar $ .when )
fonte
Aqui, o código totalmente documentado.
fonte
$.when.apply($, array)
não é o mesmo que$.when(array)
. É o mesmo que:$.when(array[0], array[1], ...)
Infelizmente não posso concordar com vocês.
Chamará
everythingDone
assim que um adiado for rejeitado , mesmo se houver outros adiados pendentes .Aqui está o script completo (eu recomendo http://jsfiddle.net/ ):
É um bug? Eu gostaria de usar isso como o cavalheiro acima descreveu.
fonte
Talvez alguém possa achar isso útil:
everythingDone não é chamado em caso de rejeição
fonte
$ .when sozinho torna possível que um retorno de chamada seja chamado quando todas as promessas passadas a ele forem resolvidas / rejeitadas. Normalmente, $ .quando recebe um número variável de argumentos, usar .apply torna possível passar uma matriz de argumentos, é muito poderoso. Para obter mais informações sobre .apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
fonte
Obrigado pela sua solução elegante:
Apenas um ponto: ao usar
resolveWith
para obter alguns parâmetros, ele quebra por causa da promessa inicial definida como indefinida. O que eu fiz para fazer funcionar:fonte