Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ECMAScript Promise.all method works with jQuery.Deferred. Why?

I was making a research for Promises in JavaScript. I'm was interesting can I combine ECMAScript Promises with other implementations, for example jQuery $.Deferred. And I was surprised when Promises.all works fine with jQuery $.Deferred. I'm trying to find the answer in jQuery source code and CommonJS Promises/A specs, but I still misunderstood why this code works as I expected(do console.log after 10 seconds, not 5 seconds):

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
});

Do you have any ideas?

Promise.all must rely on something field or method of $.Deferred to understand is resolved it or not. What is that method/field?

like image 208
Pinal Avatar asked Jul 31 '14 14:07

Pinal


People also ask

How use JQuery Deferred and Promise?

promise() will attach the methods onto it and then return this object rather than create a new one. This can be useful to attach the Promise behavior to an object that already exists. If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point.

What is Deferred method in JQuery?

Deferred() method in JQuery is a function which returns the utility object with methods which can register multiple callbacks to queues. It calls the callback queues, and relay the success or failure state of any synchronous or asynchronous function.

Does JQuery support Promise?

The . promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended. By default, type is "fx" , which means the returned Promise is resolved when all animations of the selected elements have completed.

Why do we need promises in JQuery?

The jQuery promise() is one of the default methods it is used to return the unwanted or not confirmed objects whether it is in a static or dynamic type but which has been already performed some user events, actions, and other operations that can be resolved in all the parts like collections, stacks, queues, etc but ...


1 Answers

The promises A+ specification (on which the promises unwrapping specification was based on which native promises use) was specifically built to do this.

With a design goal of libraries inter-oping well, the specification is built around a single method: .then.

The then method specifies how a continuation of a promise works. jQuery promises expose .then since version 1.8 which means they try to participate in this game. While jQuery deferreds and promises are not Promises/A+ promises - they attempt to be Promises/A promises which means the following:

return Promise.resolve($.get(...))

Will always work. A+ promises (and native promises) will assimilate every .thenable recursively and resolve with its value when you return it.

Promise.resolve({then:function(fn){ return fn(3); }}).then(function(el){
    console.log(el); // this logs 3
})

If we check the specification , we can see:

Let result be Invoke(nextPromise, "then", (resolveElement, promiseCapability.[[Reject]])).

(also related is this)

Which calls .then and resolves the next item when that .thenable resolves

jQuery's deferred uses a nonstandard promise implementation so it cannot consume native promises (That is, you can't predictably $.when a native promise. The other way around works.

like image 143
Benjamin Gruenbaum Avatar answered Sep 20 '22 01:09

Benjamin Gruenbaum