http://www.cnblogs.com/lvdabao/p/jquery-deferred.html @ Lv Tai Leopard
The first two we talked about the ES6 in the promise and promise/a+ norms, in the Promise knowledge system, jquery is certainly a necessary link, so this chapter is about the promise in jquery, which is what we know deferred object. In fact, there are a lot of articles on the internet before about jquery deferred objects, but always like to mix Ajax and deferred together, easy to confuse people. When, do, promise, success, error, fail, then, resolve, reject, always so many methods can not be rubbed together, need to be smoothed, which is the method of deferred object, Which is the grammatical sugar of Ajax, we need to know clearly.
first speak $. Deferredjquery with $. Deferred implements the promise specification, $. What the hell is deferred? Still the old method, print out to see, first has a visual impression:
var def = $. Deferred (); Console.log (Def);
The output is as follows: $. Deferred () Returns an object that we can call a Deferred object with some familiar methods such as done, fail, then, and so on. jquery is using this deferred object to register the callback function of an asynchronous operation, modifying and passing the state of the asynchronous operation. The basic usage of the deferred object is as follows, and in order to not be confused with Ajax, we still cite settimeout example:
function RunAsync () { var def = $. Deferred (); Do some asynchronous operations setTimeout (function () { console.log (' execution complete '); Def.resolve (' whatever data '); }; return def;} RunAsync (). Then (function (data) { console.log (data)});
In the Runasync function, we first define a Def object, then perform a delay operation, call Def.resolve () after 2 seconds, and finally return the DEF as a function. When you call Runasync, the Def object is returned, and then we can execute the callback function. Does it feel like a ES6 promise? Let's recall the example of ES6 in the first article:
function RunAsync () { var p = new Promise (function (resolve, reject) { //Do some asynchronous operation SetTimeout (function () { console.log (' execution complete '); Resolve (' random data '); } ); return p; } RunAsync ()
The difference is where a glance is known. Since the Def object of jquery has a resolve method in its own right, we did not pass in a function parameter like ES6 when creating the Def object, which is empty. This can be called directly after Def.resolve (). This also has a disadvantage, because the execution Runasync () can get the Def object, and the Def object has the Resolve method, then can not be outside to modify the state of Def? For example, I modified the above code as follows:
var d = runAsync ();d. Then (function (data) { console.log (data)});d. Resolve (' end outside ');
What is the phenomenon? Does not output "execute complete" in 2 seconds, but instead outputs "ends externally" directly. Because we did not wait for his own resolve before the execution of the asynchronous operation was completed, it was externally given to resolve. This is obviously risky, such as an asynchronous operation you define and a callback function, which may be terminated prematurely by someone else, and your callback function cannot be executed. What to do? jquery provides a promise method, on the Def object, he can return a restricted deferred object, so-called limited is no resolve, reject and other methods, can not be changed from the outside of his state, the use of the following:
function RunAsync () { var def = $. Deferred (); Do some asynchronous operations setTimeout (function () { console.log (' execution complete '); Def.resolve (' whatever data '); }; return Def.promise (); is called here}
There is no resolve method on the returned object, and there is no way to change his state from the outside. This promise name is a bit of wonderful, easy to let us confuse, in fact, he is a way to return the restricted deferred object, and Promise specification has no relationship, just the name is called Promise. Although the name is wonderful, it is recommended.
Then the chained callSince deferred is also an implementation of the promise specification, other features must also be supported. The use of chained calls is as follows:
var d = runAsync ();d. Then (function (data) { console.log (data); return RunAsync2 ();}). Then (the function (data) { console.log (data); return runAsync3 ();}). Then (function (data) { console.log (data);});
As with the example in our first article, we can refer to it.
Done vs. failWe know that in the Promise specification, the then method accepts two parameters, namely, execution completion and execution failed callbacks, while jquery is enhanced and can accept the third parameter, which is the callback at the pending state, as follows:
Deferred.then (Donefilter [, Failfilter] [, Progressfilter])
In addition to this, jquery adds two syntax sugar methods, done and fail, which are used to specify the callback for execution completion and execution failure, which means the code:
D.then (function () { console.log (' execution done ');}, function () { console.log (' execution failed ');});
is equivalent to this code:
D.done (function () { console.log (' execute complete ');}). Fail (function () { console.log (' execution failed ');});
the use of alwaysThere is also a always method on the deferred object of jquery, whether execution is complete or failed, all will be executed, somewhat similar to the one in Ajax. Don't dwell on it.
the use of $.whenIn jquery, there is also a $.when method to implement promise, which, like the All method function in ES6, performs asynchronous operations in parallel and executes the callback function after all asynchronous operations have been executed. But $.when is not defined in $. Deferred, look at the name to know, $.when, it is a separate method. Unlike the ES6 all parameter, it accepts not arrays, but multiple deferred objects, as follows:
$.when (RunAsync (), RunAsync2 (), runAsync3 ()). Then (function (Data1, data2, data3) { console.log (' Full execution complete '); Console.log (Data1, data2, data3);});
Isn't there a race method in jquery like ES6? That's the way to run fast. Yes, not in jquery. The above is the common method of deferred objects in jquery, and there are some other ways to use it, simply do not remember it. Now it's time to talk about Ajax.
the relationship between Ajax and deferredjquery Ajax returns a restricted deferred object, remembering the restricted deferred object, which means there is no resolve method and reject method, and cannot change state from the outside. Think of it too, you send an AJAX request, others from other places to you canceled, also can't stand. Since it is a deferred object, all of the features that we have mentioned above, Ajax can be used as well. For example, chaining calls, sending multiple requests in succession:
req1 = function () { return $.ajax (/*...*/);} REQ2 = function () { return $.ajax (/*...*/);} REQ3 = function () { return $.ajax (/*...*/);} REQ1 (). Then (REQ2), then (REQ3). Do (function () { console.log (' request completed ');});
Understand the essence of the Ajax return object, then we use it handy.
success, error and completeThese three methods may be the most we use, using the same:
$.ajax (/*...*/). Success (function () {/*...*/}). Error (function () {/*...*/}). Complete (function () {/*...*/})
A callback that represents the success, failure, or end of an AJAX request. What is the relationship between these three methods and deferred? In fact, is the syntax of sugar, success corresponding to done,error corresponding fail,complete always, so, just to be consistent with the name of the Ajax parameter, more convenient for everyone to remember, look at the source:
Deferred.promise (JQXHR). Complete = Completedeferred.add;jqxhr.success = Jqxhr.done;jqxhr.error = JqXHR.fail;
The complete line is written in order to reduce the duplication of code, in fact, the done and fail are called again, and always in the same code. As can be seen from Deferred.promise (JQXHR), Ajax returns a restricted deferred object. jquery adds all these grammatical sugars, even though the threshold for getting started is lower, but it creates a certain degree of confusion. Some people have written for a long time, but have not known the principle of the, in the interview can only answer a few fur, which is very bad. That's why I wrote this article. jquery in deferred object involves a lot of methods, this article as far as possible to introduce, hope to help you clear ideas. A summary is: $. Deferred implements the promise specification, then, do, fail, always is the method of deferred object. $.when is a global approach for running multiple asynchronous tasks in parallel, with all of ES6 being a feature. Ajax returns an deferred object, success, error, and complete are the syntactic sugars provided by Ajax, and the function is consistent with the done, fail, and always of the deferred object. Just the sauce.
Plain English explaining Promise (iii) Understanding the Promise in jquery