JQuery. deferred

Source: Internet
Author: User

JQuery. deferred

I. Preface
Before jQuery1.5, if you need to perform multiple Ajax operations, we generally use the following two methods:

1). call Ajax in sequence

$.ajax({ success: function() {   $.ajax({ success: function() {    $.ajax({ //callbacks...         });   }); });  

This method has poor code readability, low efficiency, and difficulty, making debugging and troubleshooting complicated.

2). call Ajax in parallel

var promises = []; $.ajax({  success: function() {     promises.push('resolved');     check();   } }); $.ajax({   success: function() {     promises.push('resolved');     check();  } }); $.ajax({   success: function() {     promises.push('resolved');     check();   } }); var check = function() { //checks for all 3 values in the promises array }

This method is good for callbacks function calls, and data is obtained in parallel and readable. The disadvantage is the lengthy code, poor scalability, and high complexity of debugging and troubleshooting.

After jQuery1.5, the deferred object is added. Therefore, we can use the following method to achieve the same requirements as above.

1) Promise

var address = $.ajax({}); var tweets = $.ajax({}); var facebook = $.ajax({}); render_side_bar = function(address, tweets, facebook){   //render sidebar }render_no_side_bar = function () { }$.when(address, tweets, facebook).then(render_side_bar, render_no_side_bar)

It can be seen that the code is readable, highly scalable, and greatly reduces the complexity of debugging and troubleshooting.

So the question is, what exactly are promises and deferred objects?

Ii. Details
2. What is a deferred object?
The deferred object is a latency object. It is a callback function solution introduced by jQuery 1.5. It represents an operation to be completed and provides some methods to help you use it.

The deferred object is the implementation of the Promises interface. The jqXHR object returned by jQuery 1.5 and later Ajax is a deferred object.

2. Benefits of the deferred object
2. 1. Specify multiple callback functions for the same operation
One of the advantages of a deferred object is that it allows you to add multiple callback functions for an operation, which cannot be implemented in traditional ajax.

$.ajax("test.html")  .done(function(){ alert("first success callback!");} )  .fail(function(){ alert("there is an error!"); } )  .done(function(){ alert("second success callback!");} );

2. Specify the same callback function for multiple operations
The second benefit of the deferred object is that it allows you to specify the same callback function for multiple operations, which cannot be implemented in traditional ajax.

$.when($.ajax({}), $.ajax({}))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

. Callback functions for non-Ajax operations
The third advantage of the deferred object is that it no longer sticks to ajax operations. Any operation (ajax operation or local operation/asynchronous operation or synchronous operation) can use the deferred object and specify the callback function.

A typical time-consuming operation

var dfd = $.Deferred(); // create a deferred object  var wait = function(dtd){    var tasks = function(){      alert("over!");      dtd.resolve(); // change the state of the deferred object from pending to resolved    };    setTimeout(tasks,50000);    return dtd;  };
$.when(wait(dtd))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

2. 4. chained call
The traditional ajax operations in jQuery are as follows:

$.ajax({  url: "",   success: function(){    alert("success!");   },   error:function(){    alert("error!");   }});

Success specifies the callback function after the ajax operation is successful, and error specifies the callback function after the ajax operation fails. Before jQuery1.5, Ajax operations return an XMLHTTPRequest object and do not support chained operations. Starting from version 1.5, the ajax operation returns the jqXHR object, which is a deferred object. A significant benefit of the deferred object is that it can be chained, because all methods of the deferred object return the deferred object.

The current ajax operations are written as follows:

$.ajax({})  .done(function(){ alert("success!"); })  .fail(function(){ alert("fail!"); });

The comparison between the two methods shows that done () is equivalent to the success method of traditional ajax operations, and fail () is equivalent to the fail method of traditional ajax operations. Compared with traditional writing, code readability is improved.

3. deferred object Method
3.1 basic usage
(1). Generate a deferred object

Var dfd = $. Deferred (); // create a deferred object
(2). deferred object status

The deferred object has three states.

Pending:Indicates that the operation is in the unfinished state, and any deferred (Delay) object starts in the pending state.
Resolved:The operation is successful.
Rejected:Operation failed.
The state () method returns the current state of the deferred object.

$.Deferred().state(); // 'pending'$.Deferred().resolve().state(); // 'resolved'$.Deferred().reject().state(); // 'rejected'

(3). Change the state of the deferred object

Call deferred. resolve () or deferred. resolveWith () to convert the state of Deferred (deferred) to resolved (resolved), and immediately execute any doneCallbacks in the settings.

var callbackFunc = function(){console.log(arguments[0]);}var dfd = $.Deferred();dfd.done(callbackFunc);dfd.resolve("hello"); //'hello'

Call deferred. reject () or deferred. rejectWith () to convert the state of Deferred (deferred) to rejected (denied), and immediately execute any failCallbacks in the settings.

var callbackFunc = function(){console.log(arguments[0]);}var dfd = $.Deferred();dfd.fail(callbackFunc);dfd.reject("fail"); //'fail'

(4) bind the callback function

When the deferred object status changes, the callback function is triggered. Any callback that uses deferred. then (), deferred. always (), deferred. done (), or deferred. fail () to add to this object is queued for execution.

Pending --> resolved: execute any doneCallbacks (specified by done () in the settings. The parameter is passed to doneCallbacks by resolved.
Pending --> rejected: execute any failCallbacks (specified by fail () in the settings. The parameter is passed to failCallbacks by resolved.
Pending --> resolved/rejected: run the callbacks specified by always (). The parameter is passed to callbacks by resolved.

var f1 = function(){console.log("done");},    f2 = function(){console.log("fail");},    f3 = function(){console.log("always");};var dfd = $.Deferred();dfd.done(f1).fail(f2).always(f3);//ifdfd.resolve(); //'done' 'always'//ifdfd.reject(); //'fail' 'always'

If a callback is attached after the status change, the callback is executed immediately, so you do not have to worry about when the deferred object will be resolved or rejected, because the parameter will be correctly passed to callbacks at any time.

var fun1 = function(){console.log(arguments[0]);},  fun1 = function(){console.log(arguments[0]);};var dfd = $.Deferred();dfd.done(fun1);dfd.resolve("hello"); //'hello'dfd.done(fun2); //'hello'

3.2.deferred object Method
(1) $. Deferred ([beforeStart]) -- creates a deferred object. The parameter type is Function, which is a Function called before the constructor.

var func = function(){console.log("start");} var dfd = $.Deferred(func); //'start' create a deferred object

(2) deferred. done (doneCallbacks [, doneCallbacks]) -- calls the Add handler when the deferred (latency) object is resolved.

Args: accepts one or more parameters. All parameters can be a single function or function array. When the deferred (latency) object is resolved, doneCallbacks is called. The callback is executed in the order they are added.

var func1 = function(){console.log("1");},   func2 = function(){console.log("2");},   func3 = function(){console.log("3");};var dfd = $.Deferred();dfd.done([func1,func2],func3,[func2,func1]);dfd.resolve(); // "1 2 3 2 1"

(3) deferred. fail (failCallbacks [, failCallbacks]) -- calls the Add handler when the deferred (latency) object is rejected.

Args: accepts one or more parameters. All parameters can be a single function or function array. When a deferred (delayed) object is rejected, failCallbacks is called. The callback is executed in the order they are added.

var func1 = function(){console.log("1");},   func2 = function(){console.log("2");},   func3 = function(){console.log("3");};var dfd = $.Deferred();dfd.fail([func1,func2],func3,[func2,func1]);dfd.reject(); // "1 2 3 2 1"

(4) deferred. resolve (args) and deferred. resolveWith (context [, args]) -- resolves the Deferred (latency) object and calls any doneCallbacks Based on the given args parameter (resolveWith given context.

Parameter: args -- type (object), an optional parameter passed to the callback function (doneCallbacks,

Context -- type (object), Context (context) is passed as this object to the completion callback function (doneCallbacks ).

var func = function(arg){console.log(arg);};$.Deferred().done(func).resolve("done!"); //'done!'var func = function(arg1,arg2){console.log(arg1.name + ',' + arg2);};$.Deferred().done(func).resolve({name:'Lucy'},'How are you!'); // 'Lucy,How are you!'

The difference between resolve and resolveWith is equivalent to the difference between fire and fireWith.

var func = function () {  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1] + ' ' + arguments[2]);};$.Deferred().done(func).resolveWith({ name: "Lucy" }, ["How", "are", "you!"]);//'Lucy,How are you!'

(5) deferred. reject (args) and deferred. rejectWith (context [, args]) -- rejects the Deferred (latency) object and calls any failCallbacks Based on the given args parameter (rejectWith given context.

Parameter: args -- type (object), an optional parameter passed to the callback function (doneCallbacks,

Context -- type (object), Context (context) is passed as this object to the completion callback function (doneCallbacks ).

var func = function(arg){console.log(arg);};$.Deferred().fail(func).reject("error!"); //'error!'var func = function(ctx,arg){console.log(ctx.name + ',' + arg);};$.Deferred().fail(func).reject({name:'Mark'},'What happend!'); // 'Mark,What happend!'

The difference between reject and rejectWith is equivalent to the difference between fire and fireWith.

var func = function () {  console.log(this.name + ',' + arguments[0] + ' ' + arguments[1]);};$.Deferred().fail(func).rejectWith({ name: "Mark" }, ["what", "happend!"]); // 'Mark,What happend!'

(6) deferred. promise ([target]) -- returns the Promise (promise) object of Deferred (latency.

Optional. If there is no parameter, a Promise (Promise) object is returned. The Promise (Promise) object only exposes the delay methods (then, done, fail, always, pipe, progress, state, and promise) does not expose any delay methods (resolve, reject, destroy y, resolveWith, rejectWith, and policywith) used to change the state ). Using Promise will prevent others from damaging your promise.

function asyncEvent() {   var dfd = jQuery.Deferred();    // Resolve after a random interval    setTimeout(function () {       dfd.resolve("hurray");    }, Math.floor(400 + Math.random() * 2000));    // Reject after a random interval    setTimeout(function () {       dfd.reject("sorry");    }, Math.floor(400 + Math.random() * 2000));    // Show a "working..." message every half-second    setTimeout(function working() {       if (dfd.state() === "pending") {          dfd.notify("working... ");           setTimeout(working, 500);        }     }, 1);      // Return the Promise so caller can't change the Deferred      return dfd.promise(); }// Attach a done, fail, and progress handler for the asyncEvent$.when(asyncEvent()).then(    function (status) {       alert(status + ", things are going well");    },    function (status) {       alert(status + ", you fail this time");    },    function (status) {       alert(status);    });

When a parameter exists, the event is bound to the parameter, and then the parameter object is returned (actually an extended Promise (Promise) object ).

var obj = {  hello: function (name) {    alert("Hello " + name);  }},// Create a Deferreddfd = $.Deferred();// Set object as a promisedfd.promise(obj);// Resolve the deferreddfd.resolve("John");// Use the object as a Promiseobj.done(function (name) {   obj.hello(name); // will alert "Hello John"}).hello("Karl");

(7) $. when (deferreds) -- provides a method to execute the callback function of one or more objects.

Parameter: type (Deferred), one or more delayed objects, or common JavaScript objects.

Only one separate Deferred object is input, and its Promise object is returned.

function func() {  var dfd = $.Deferred();  setTimeout(function () {    dfd.resolve("hurry");  }, 500);  return dfd.promise();};$.when(func()).done(function (arg) {  alert(arg); /*alert "hurry"*/});

If a non-Deferred and Promise object is passed in, the parameter will be treated as a delayed object to be resolved (resolved), and any doneCallbacks bound to the above will be executed immediately.

$.when( { name: 123 } ).done(  function(arg) { alert(arg.name); } /* alerts "123" */);

If no parameter is specified, a Promise object in the resolved (solution) state is returned.

$.when().state(); // "resolved"

Multiple Deferred objects are specified. This method tracks all the aggregated states that have passed Deferreds based on a new "host" Deferred (latency) object and returns a Promise object. When all the delayed objects are resolved (resolve), the "host" Deferred (latency) object will solve (resolved) This method, or when one of the delayed objects is rejected, the "host" Deferred (latency) object will reject (reject) This method.

var d1 = $.Deferred();var d2 = $.Deferred(); $.when( d1, d2 ).done(function ( v1, v2 ) {  console.log( v1 ); // "Fish"  console.log( v2 ); // "Pizza"}); d1.resolve( "Fish" );d2.resolve( "Pizza" );

(8) deferred. then (doneFilter [, failFilter] [, progressFilter]) -- when the Deferred (latency) object is resolved, rejected, or still in progress, add a handler is called.

Parameters:

DoneFilter -- type (Function), a Function called when the Deferred (latency) object is resolved.
FailFilter -- type (Function), a Function called when the Deferred (Delay) object is rejected. Optional.
ProgressFilter -- type (Function), a Function called when the Deferred (Delay) object generates a progress notification. Optional.
In fact, the then method can be understood as writing done (), fail (), and progress () together.

var filterResolve = function () {   var dfd = $.Deferred(),     filtered = dfd.then(function (value) { return value * 2; });   dfd.resolve(5);   filtered.done(function (value) { console.log(value); });};filterResolve(); //'10'var defer = $.Deferred(),   filtered = defer.then(null, function (value) {     return value * 3;   });defer.reject(6);filtered.fail(function (value) {   alert("Value is 3*6 = " + value);});

(9) deferred. always (alwaysCallbacks [, alwaysCallbacks]) -- execute alwaysCallbacks when the Deferred (latency) object is resolved or rejected.

As the name suggests, alwaysCallbacks will be called as long as the status of the Deferred object changes (solved or rejected.

(10) deferred. state () -- get the current status of a Deferred (latency) object. No parameters are accepted.

$. Deferred (). state (); // "pending"
The preceding describes three States of a deferre (latency) object. This method is very useful for debugging. For example, you can determine whether a deferred object is in the resolved state before preparing a reject.

(11) deferred. Policy (args) and deferred. policywith ()

(12) deferred. progress ()

(13) deferred. pipe ()

(14). promise ()

(15) deferred. isRejected () and deferred. isResolved () -- this method has been deprecated since jQuery 1.7 and has been deleted from later jQuery class libraries. You can use the state () method to replace these two methods.

(16) deferred. pipe () -- deprecated from jQuery 1.8.

4. Under what circumstances will deferred objects and Promises be used?
As mentioned above, under what circumstances should we use the Deferred object and Promises object?

(1) complex animations

I don't know when the animation ends, but I have to do some operations at the animation end or start other animations. In this case, if I use another method, it is easy to cause poor code readability, especially some other operations, such as rendering and form operations. Now jQuery returns a Promise for your animation operations, in this way, these animations can be chained.

(2) processing queue

Copy codeThe Code is as follows: window. queue = $. when () $ ('# list '). on ('click', function () {window. queue = window. queue. then (function () {// do the thing })})
(3) The Wait promise

function wait(ms) {   var deferred = $.Deferred();   setTimeout(function(){deferred.resolve()}, ms);  return deferred.promise(); }wait(1500).then(function () {    // After 1500ms this will be executed });

(4) typical Ajax operations

$.when($.ajax({}), $.ajax({}))  .done(function(){ alert("success!"); })  .fail(function(){ alert("error!"); });

(5) some time-consuming large-cycle operations

The above is all the content of this article, hoping to help you learn.

Articles you may be interested in:
  • Use the code of the deferred object in jQuery 1.5)
  • Use the deferred object in jQuery1.5 to view Promise with a magnifier
  • Detailed description of jQuery's deferred object usage
  • Use jQuery's deferred object to asynchronously load JS files in sequence
  • Basic jquery tutorial-deferred object usage
  • Deferred objects of jQuery
  • Detailed description of jQuery's deferred object
  • The following uses the $. Deferred object in jQuery as an example to explain how the promise object handles the asynchronous problem.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.