O método ECMAScript Promise.all funciona com jQuery.Deferred.Por que?
-
22-12-2019 - |
Pergunta
Eu estava fazendo uma pesquisa sobre Promessas em JavaScript.Achei interessante poder combinar promessas ECMAScript com outras implementações, por exemplo jQuery $.Deferred
.E fiquei surpreso quando Promises.all
funciona bem com jQuery $.Deferred
.Estou tentando encontrar a resposta no código-fonte jQuery e nas especificações CommonJS Promises/A, mas ainda não entendi por que esse código funciona como eu esperava (fazer console.log
após 10 segundos, não 5 segundos):
var promise = new Promise(function (resolve, reject) {
setTimeout(function () {
resolve();//resolve first promise after 5 secs
console.log('Promise resolved');
}, 5000);
});
var deferred = $.Deferred();
setTimeout(function () {
deferred.resolve();//resolve after 10 seconds
console.log('Deferred resolved');
}, 10000);
Promise.all([promise,deferred]).then(function () {
console.log('All is done');//log after 10 seconds
});
Você tem alguma ideia?
Promise.all
deve confiar em algo campo ou método de $.Deferred
entender se está resolvido ou não.Qual é esse método/campo?
Solução
A especificação de promessas A+ (na qual a especificação de desembrulhamento de promessas foi baseada no uso das promessas nativas) foi construída especificamente para fazer isso.
Com o objetivo de design de bibliotecas que interagem bem, a especificação é construída em torno de um único método: .then
.
O método then especifica como funciona a continuação de uma promessa.jQuery promete expor .then
desde a versão 1.8 o que significa que eles tentam participar deste jogo.Embora o jQuery adie e as promessas sejam não Promessas/Promessas A+ - elas tentam ser Promessas/Promessas A, o que significa o seguinte:
return Promise.resolve($.get(...))
Sempre funcionará.As promessas A+ (e as promessas nativas) assimilarão todos .then
capaz recursivamente e resolver com seu valor quando você o retornar.
Promise.resolve({then:function(fn){ return fn(3); }}).then(function(el){
console.log(el); // this logs 3
})
Se verificarmos o especificação , nós podemos ver:
Deixar resultado ser Invocar (próxima promessa,
"then"
, (resolveElement, promessaCapacidade.[[Rejeitar]])).
(também relacionado é esse)
Quais chamadas .then
e resolve o próximo item quando isso .then
capaz resolve
O adiado do jQuery usa uma implementação de promessa fora do padrão, portanto não pode consumir promessas nativas (ou seja, você não pode previsivelmente $.when
uma promessa nativa.O contrário funciona.