Transfer from https://www.cnblogs.com/losesea/p/4415676.html
The deferred object is the implementation of jquery for the promises interface. It is a common interface for non-synchronous operations and can be seen as a waiting task, and the developer sets it up through a number of interfaces. In fact, it acts as a proxy, wrapping those non-synchronous operations into objects with some uniform characteristics, typically AJAX operations, Web page animations, web workers, and so on.
All of jquery's Ajax operation functions, which are returned by default, are a deferred object.
What is promises?
Because of the JavaScript single-threaded nature, if an operation takes a long time, other operations must wait in line. To prevent the entire program from losing its response, the usual workaround is to write the following operations as "callback functions" (callback). While this solves the problem, there are some notable drawbacks:
1. Callback functions are often written in the form of function parameters, resulting in the input and output of the function is very confusing, the whole program is not readable; 2. Callback functions can often specify only one, and if there are multiple operations, the callback function needs to be overwritten. 3. The process of the entire process is disrupted, the debug and debugging difficulties are correspondingly increased.
Promises is to solve these problems, the main purpose of this is to replace the callback function, a non-synchronous operation of the solution. Its core idea is to let the non-synchronous operation return an object, and the other operations are done for this object. For example, assume that an AJAX operation returns a Promise object.
The code is as follows: var promise = Get (' http://www.example.com ');
The Promise object then has a then method that can be used to specify the callback function. Once the asynchronous operation is complete, the specified callback function is invoked.
The code is as follows: Promise.then (function (content) {Console.log (content)})
The above two pieces of code can be merged together, so that the process of the program to see more clearly.
The code is as follows: Get (' http://www.example.com '). Then (function (content) {Console.log (content)})
Prior to version 1.7, jquery's Ajax operations were preceded by a callback function.
The code is as follows: $.ajax ({url: "/echo/json/", success:function (response) {console.info (response.name); } });
After version 1.7, the AJAX operation returns the Promise object directly, which means that the callback function can be specified using the then method.
The code is as follows: $.ajax ({url: "/echo/json/",}). Then (function (response) {console.info (response.name);});
Methods for deferred objects
$.deferred () method
The effect is to generate a deferred object.
The code is as follows: var deferred = $.deferred ();
Done () and fail ()
Both methods are used to bind the callback function. Done () specifies the callback function after the successful asynchronous operation, and fail () specifies the callback function after the failure.
The code is as follows: var deferred = $. Deferred (); Deferred.done (function (value) {alert (value);});
They return the original deferred object, so they can be chained, followed by other methods (including done and fail).
Resolve () and reject ()
These two methods are used to change the state of the deferred object. Resolve () changed the state to a non-synchronous operation successfully, reject () changed to operation failed.
The code is as follows: var deferred = $. Deferred (); Deferred.done (function (value) {alert (value);}); Deferred.resolve ("Hello World");
Once resolve () is called, the callback function specified by the done () and then () method is executed sequentially, and the callback function specified by the fail () and then () method is executed in turn once The Reject () is called.
State method
This method is used to return the current state of the deferred object.
The code is as follows: var deferred = new $. Deferred (); Deferred.state (); "Pending" Deferred.resolve (); Deferred.state (); "Resolved"
The method has a return value of three:
1.pending: Indicates that the operation has not been completed. 2.resolved: Indicates successful operation. 3.rejected: Indicates that the operation failed.
Notify () and Progress ()
Progress () is used to specify a callback function that will be executed when the Notify () method is called. It is intended to provide an interface that enables certain operations to be performed during the execution of a non-synchronous operation, such as the progress of periodically returning a progress bar.
The code is as follows: var userprogress = $. Deferred (); var $profileFields = $ ("input"); var totalfields = $profileFields. Length userprogress.progress (function ( Filledfields) { var pctcomplete = (filledfields/totalfields) *100; $ ("#progress"). HTML (pctcomplete.tofixed (0)); }); userprogress.done (function () { $ ("#thanks"). HTML ("Thanks for completing your profile!"). Show (); }); $ ("input"). On ("Change", function () { var filledfields = $profileFields. Filter ("[value!=]"). Length; userprogress.notify (Filledfields); if (filledfields = = totalfields) { Userprogress.resolve (); } });
Then ()
Then () is also the function of specifying a callback function, which can accept three parameters, that is, three callback functions. The first parameter is the callback function that is called when resolve, the second parameter is the callback function that is called when reject, and the third parameter is the callback function called by the Progress () method.
The code is as follows: Deferred.then (Donefilter [, Failfilter] [, Progressfilter])
Before jquery 1.8, then () was just. Done (). Fail () syntax sugar, the two formulations are equivalent. After jquery 1.8, then () returns a new deferred object, and done () returns the original deferred object. If then () the callback function specified has a return value, the return value is passed as a parameter to the following callback function.
The code is as follows: var defer = jquery.deferred (); Defer.done (b) {return a * b;}). Done (function (result) {Console.log ("result =" + result);}). Then (function (A, b) {return a * b;}). Done (function (result) {Console.log ("result =" + result);}). Then (function (A, b) {return a * b;}). Done (function (result) {Console.log ("result =" + result);}); Defer.resolve (2, 3);
Before the jquery 1.8 release, the result of the above code was:
The code is as follows: result = 2 result = 2 result = 2
After the jquery 1.8 version, the returned result is
The code is as follows: result = 2 result = 6 result = NaN
This requires special attention.
The code is as follows: $.ajax (URL1, {dataType: "JSON"}). Then (function (data) {return $.ajax (URL2, {data: {user:data.userId} } ); }). Done (function (data) {//data obtained from URL2});
The last done method of the above code deals with the data obtained from URL2, not the data obtained from URL1.
Using then () modifies the property of the return value, and we can process the value returned by the previous operation before invoking the other callback function.
The code is as follows: var post = $.post ("/echo/json/"). Then (function (p) {return p.firstname; }); Post.done (function (r) {Console.log (r);});
The above code first uses the then () method to remove the required fields (FirstName) from the returned data, so that the subsequent operation can only process this field.
Sometimes, an AJAX operation returns a JSON string with an error property that indicates a fault occurred. At this time, the traditional approach can only be done by doing () to determine whether an error occurred. With the then () method, you can have the deferred object call the Fail () method.
The code is as follows: var mydeferred = $.post ('/echo/json/', {json:JSON.stringify ({' Error ': true})}) . Then (function (response) { if (response.error) { return $. Deferred (). Reject (response); } return response; },function () { return $. Deferred (). Reject ({error:true}); } ); Mydeferred.done (function (response) { $ ("#status"). HTML ("success!"); }). Fail (function (response) { $ ("#status"). HTML ("an Error occurred "); });
Always ()
Always () is also the specified callback function, either resolve or reject to be called.
Pipe method
The pipe method takes a function as a parameter, indicating that the callback function specified by the pipe method is run before calling the then method, the Done method, the Fail method, and the callback function specified by the Always method. It is usually used to perform preliminary processing of the data returned by the server.
Promise Object
In most cases, we do not want the user to change the state of the deferred object externally. At this point, you can return a promise object against it, based on the deferred object. We can take the latter into consideration, that promise is a read-only version of deferred, or more generally understood as promise is a commitment to the task that will be accomplished.
You can add a callback function to the original deferred object by promise the object, query its state, but cannot change its state, that is, the Promise object does not allow you to invoke the resolve and reject methods.
The code is as follows: function getpromise () {return $. Deferred (). Promise (); } try{getpromise (). Resolve ("a");} catch (Err) {Console.log (err);}
The above code will be faulted, showing typeerror {}.
The Ajax () method of jquery Returns a Promise object. In addition, the animation class operation can also use the Promise object.
The code is as follows: var promise = $ (' Div.alert '). FadeIn (). Promise ();
$.when () method
$.when () accepts multiple deferred objects as parameters, and when all of them run successfully, the callback function of the resolved state is called, but whenever one of them fails, the rejected state callback function is called. It is equivalent to merging multiple non-synchronous operations into one.
The code is as follows: $.when ($.ajax ("/main.php"), $.ajax ("/modules.php"), $.ajax ("/lists.php")). Then (Successfunc, Failu REFUNC);
The code above indicates that the callback function specified by the then method is not executed until the three Ajax operations have finished.
When the method executes how many operations, the callback function has the number of parameters, corresponding to each of the previous operations return results.
The code is as follows: $.when ($.ajax ("/main.php"), $.ajax ("/modules.php"), $.ajax ("/lists.php")). Then (function (RESP1, R ESP2, RESP3) {console.log (RESP1); Console.log (RESP2); Console.log (RESP3); });
The callback function for the above code has three parameters, Resp1, resp2, and RESP3, which in turn correspond to the results of the previous three Ajax operations.
Another effect of the When method is that if its arguments return not a deferred or Promise object, then the callback function of the When method runs immediately.
The code is as follows: $.when ({testing:123}). Done (function (x) {console.log (x.testing);//"123"});
The callback function specified in the above code will run immediately after the When method.
With this feature, we can write an asynchronous operation function that has a caching effect. That is, the first time the function is called, the asynchronous operation is performed, and the function is called later, and the cached result is returned.
The code is as follows: function Maybeasync (num) {var DFD = $. Deferred (); if (num = = 1) {setTimeout (function () {dfd.resolve (num); }, 100); return Dfd.promise (); } return num; } $.when (Maybeasync (1)). Then (function (RESP) {$ (' #target '). Append (' <p> ' + resp + ' </p> ');}); $.when (Maybeasync (0)). Then (function (RESP) {$ (' #target '). Append (' <p> ' + resp + ' </p> ');});
The above code indicates that if the parameter of the Maybeasync function is 1, an asynchronous operation is performed, otherwise the cached result is returned immediately.
Instance
Wait method
We can write a wait method with the deferred object, which indicates how many milliseconds to wait before executing.
The code is as follows: $.wait = function (time) {return $. Deferred (function (DFD) {setTimeout (dfd.resolve, time); }); }
Here's how to use it:
The code is as follows: $.wait. Then (function () {alert ("Hello from the future!");});
Rewriting the SetTimeout method
On the basis of the wait method above, you can also rewrite the SetTimeout method to return a deferred object.
The code is as follows: function Dosomethinglater (FN, time) {var DFD = $. Deferred (); SetTimeout (function () {Dfd.resolve (FN ()); }, Time | | 0); return Dfd.promise (); } var promise = Dosomethinglater (function () {Console.log (' already deferred execution ');}, 100);
Custom actions use the deferred interface
We can use the deferred interface so that any operation can specify a callback function with done () and fail ().
The code is as follows: Twitter = {search:function (query) {var DFR = $. Deferred (); $.ajax ({url: "Http://search.twitter.com/search.json", Data:{q:query}, DataType: ' Jsonp ', success:dfr.re Solve}); return Dfr.promise (); } }
Here's how to use it:
The code is as follows: Twitter.search (' Intridea '). Then (function (data) {alert (data.results[0].text);});
Another advantage of the deferred object is that multiple callback functions can be attached.
The code is as follows: function dosomething (ARG) {var DFR = $. Deferred (); SetTimeout (function () {Dfr.reject ("Sorry, something went wrong."); }); return DFR; } dosomething ("Uh oh"). Done (function () {alert ("Won ' t happen, we ' re erroring here!");}). Fail (function (message) {alert (message)}); Transferred from: http://www.bitscn.com/school/Javascript/201410/338352.html
The deferred object of jquery P2