Think of a problem first: a time-consuming operation such as SetTimeout, Ajax requests, and so on, we need to execute a function done after the delay operation.
Like what:
var function () { varfunction() {alert ("execution complete! "); }; SetTimeout (Tasks, (); };
After wait has finished executing, do or fail functions are executed.
What do you do? Of course, you can perform done () or fail () in the tasks function, but not gracefully. If you join an asynchronous queue, add a method like jquery: $.when (Wait ()). Done (function () {}). Fail (function () {}).
How do you do it? The principle is simple, such as code:
var DTD = $. Deferred (); // var wait = (DTD) { var tasks = function () {alert ( "execution is complete!) "); Dtd.resolve (); // change the execution state of the deferred object }; SetTimeout (Tasks, 5000); return DTD; };
$.when (Wait (DTD)). Done (function() {alert ("Haha, success! ");}). Fail (function() {alert ("Error! "); });
Add a variable DFD object, after execution, change the state of the DFD, state changes, and trigger the corresponding method.
Specifically, look at the jquery source code.
jquery abstracts us in 3 states: Done, fail,progress; method of changing state: resolve,reject,notify; corresponding status code: Resolved,reject ; The corresponding callback object: Jquery.callbacks ("Once Memory")
To see its mapping:
var tuples = [ // action, add Listener, listener list, finalstate ["Resolve "Done", Jquery.callbacks ("Once Memory"), "resolved" ], "reject", "fail", Jquery.callbacks ("Once memory ")," rejected " ], " Notify "," Progress ", Jquery.callbacks (" Memory ")]
Deferred objects are dependent on the callbacks object implementation. Its analysis of the callbacks chapter.
Then add the appropriate method for the Deffered object.
Deferred = {};//Add [Resolve | reject | notify]deferred[Tuple[0]] =function() {deferred[tuple[0] + "with"] ( This= = = Deferred? Promise: This, arguments); return This;};//Add [resolvewith | rejectwith | notifywith]deferred[Tuple[0] + "with"] =List.firewith;//return This objectreturndeferred;//Inheriting Promise ObjectsPromisefunction(obj) {returnObj! =NULL?jquery.extend (obj, Promise): promise;} Promise.promise (deferred);
Add the appropriate method for the Promise object:
//add state, always, then, PromisePromise ={state:function() { returnState ; }, always:function() {deferred.done (arguments). Fail (arguments); return This; }, then:function(/*Fndone, Fnfail, fnprogress*/ ) { varFNS =arguments; returnJquery.deferred (function(Newdefer) {Jquery.each (tuples,function(i, tuple) {varAction = tuple[0], FN= Jquery.isfunction (fns[i]) &&fns[i];deferred[Tuple[1]] (function() { varreturned = FN && fn.apply ( This, arguments); if(Returned &&jquery.isfunction (returned.promise)) {returned.promise (). Done (Newdefer.resolve) . Fail (Newdefer.reject). Progress (newdefer.notify); } Else{newdefer[Action+ "with"] ( This= = = Promise? Newdefer.promise (): ThisFn?[returned]: arguments); } }); }); FNS=NULL; }). Promise (); },Promisefunction(obj) {returnObj! =NULL?jquery.extend (obj, Promise): promise; }},//Add PipePromise.pipe =Promise.then;//Add [done | fail | progress] = List.addpromise[tuple[1]] = List.add;
Comprehensive:
Methods of deferred:
Deferred.resolve () Manually changes the run state of the deferred object to "completed", triggering the Done () method immediately.
Deferred.reject () This method, in contrast to Deferred.resolve (), immediately triggers the Fail () method by changing the running state of the deferred object to "failed" after the call.
Deferred.notify () Manually change the running status of the deferred object to "in progress"
Deferred.state () Return status
Deferred.always ()
Deferred.then () Sometimes in order to save time, you can write the done () and fail () together, this is the then () method.
Deferred.promise () Returns a new deferred object when there is no parameter, the running state of the object cannot be changed, and when the parameter is accepted, the role is to deploy the deferred interface on the Parameter object.
Deferred.done () specifies the callback function when the operation succeeds
Deferred.fail () specifies the callback function when the operation fails
Deferred.progress () specifies the callback function when the operation is in progress
Deferred.pipe ()
$.when () specifies a callback function for multiple operations.
Methods of Promise:
In addition to the above three methods of changing the state (Resolve, Reject, notify)
Done, fail, the progress method is the Add method of the callback object;
promise[tuple[1]] = List.add;
Resolve, Reject, notify method is the fire method of callback object;
deferred[tuple[0]] = function () {
deferred[Tuple[0] + "with" (this = = = Deferred promise:this, arguments);
return this;
};
deferred[Tuple[0] + "with"] = List.firewith;
The then method feels more complex, in fact, add the pipe method content, the original content is very simple
Pipe currently used not much, meaning little, not detailed study
Finally, the When method, in fact, is to maintain a variable remaining, which triggers a callback when all is done.
Deffered analysis of the asynchronous callback object of jquery