Detailed explanation of jQuery's deferred object

Today, I will introduce a new feature introduced by the jQuery1.5.0 version - Deferred.
First, what is a Deferred object?
There are often some time-consuming operations in developing websites. These time-consuming operations include both asynchronous operations (ajax reading server data) and synchronous operations (traversing some large arrays). Usually, these operations cannot get results immediately, and we will use them at this time. Callback function (callback), the original jQuery function of callback function is relatively weak, so there is Deferred. So Deferred is jQuery's asynchronous callback solution.
Second, ajax chain writing
The traditional writing method of jQuery's ajax operation:

$.ajax({
  url: "test.php",
  success: function(){
    alert("Haha, successful!");
  },
  error:function(){
    alert("Something went wrong!");
  }
});

 
In versions below jQuery 1.5.0, the xhr object returned by $.ajax() does not have chained writing. jQuery1.5.0 or later supports chained writing.

 

 

$.ajax('test.php').done(function() {
     alert('success');
 }).fail(function() {
     alert('failed');
 });

 
As you can see, done() is equivalent to the success method, and fail() is equivalent to the error method. After using the chain writing method, the readability of the code is greatly improved.

3. It is very simple to specify multiple callback functions for the same operation

. Take the above code as an example and add it directly to the back.

 

$.ajax('test.php').done(function() {
     alert('success');
 }).fail(function() {
     alert('failed');
 }).done(function(){
     alert('success 2');
 });
 
 
4. Specifying callback functions for multiple operations

Another great benefit of deferred objects is that it allows you to specify a callback function for multiple events.
$.when($.ajax('test1.php'),$.ajax('test2.php')).done(function() {
   alert('success');
}).fail(function() {
   alert('failed');
});
 
The meaning of this code is that if both $.ajax('test1.php') and $.ajax('test2.php') succeed, execute the callback function specified by done(); if one fails or both fail If so, execute the callback function specified by fail(). 5. The callback function interface for common operations (I)

The biggest advantage of the deferred object is that it extends this set of callback function interfaces from ajax operations to all operations. That is to say, any operation - whether it is an ajax operation or a local operation, or an asynchronous operation or a synchronous operation - can use various methods of the deferred object to specify the callback function.

Let's look at a concrete example. Suppose there is a time-consuming operation wait:
  var wait = function() {
        var tasks = function() {
            alert('execution completed');
        }
        setTimeout(tasks, 3000);
  }
  
How can I specify a callback function for it?

$.when() can be used:
$.when(wait()).done(function(){
alert('success');
}).fail(function(){
alert('failed');
});
   
However, in this way, the done() method will be executed immediately, and then wait for 3s to execute the tasks function. This is not the result we want. The reason for this result is that the parameter of $.when() can only be a deferred object. So we have to rewrite wait():
    var dtd = $.Deferred();//Create a Deferred object
    var wait = function(dtd) {
        var tasks = function() {
            alert('execution completed');
            dtd.resolve();//Change the execution state of the Deferred object
        }
        setTimeout(tasks, 3000);
        return dtd;
    }
    $.when(wait(dtd)).done(function() {
        alert('success');
    }).fail(function() {
        alert('failed');
    });
 
After the wait() function runs, the callback function specified by the done() method will be automatically run.

Detailed explanation: deferred.resolve() method and deferred.reject() method
To understand these two methods, first understand the three execution states of the deferred object: 1, pending: the deferred execution state is not completed 2, resolved: the deferred execution state is completed 3, rejected: the deferred execution status failed to execute the deferred.resolve() method, the deferred execution status was never completed to the completed status (ie: resolved status), the done callback function was executed, the deferred.reject() method was executed, and the deferred execution status was never Completion becomes a failed state (ie: rejected state), and the fail callback function is executed. 6. The deferred.promise() method In the
above method, since dtd is a global object, its execution state can be changed from the outside.

See the code below:
 var dtd = $.Deferred(); // create a new Deferred object

  var wait = function(dtd){

    var tasks = function(){

      alert("Completed!");

      dtd.resolve(); // Change the execution state of the Deferred object

    };

    setTimeout(tasks,5000);

    return dtd;

  };

  $.when(wait(dtd))

  .done(function(){ alert("Haha, it worked!"); })

  .fail(function(){ alert("Something went wrong!"); });

  dtd.resolve();
 

A line of dtd.resolve() is added at the end of the code, which changes the execution state of the dtd object, so the done() method is executed immediately, and the prompt box of "Haha, it's successful!" pops up, and then pops out after 5 seconds "Executed!" prompt box.

To avoid this, jQuery provides the deferred.promise() method. The deferred object generated by the deferred.promise() method cannot change the execution state of the deferred (that is, the deferred.resolve() method and deferred.reject() method are not supported), but the done and fail callback functions can still be executed. Example:
     var wait = function(dtd) {    
        var dtd = $.Deferred(); //Inside the function, create a new Deferred object
        var tasks = function() {      
            alert("Completed!");      
            dtd.resolve(); // Change the execution state of the Deferred object

                
        };

        setTimeout(tasks, 5000);
        return dtd.promise(); // return the promise object
    };
      
    $.when(wait()).done(function() {
        alert("Haha, successful!");
    }).fail(function() {
        alert("Something went wrong!");
    });
 
 
Seven, $.Deferred

Another way to prevent the execution state from being changed externally is to use the constructor $.Deferred() of the deferred object.

At this time, the wait function remains unchanged, and we pass it directly into $.Deferred():
    var awit = function(dtd) {
        var tasks = function() {
            alert('execution completed');
            dtd.resolve();
        }
        setTimeout(tasks, 3000);
        return dtd.promise();
    }
    $.Deferred(awit).done(function() {
        alert('success');
    }).fail(function() {
        alert('failed');
    });


jQuery stipulates that $.Deferred() can accept a function name (note that it is the function name) as a parameter, and the deferred object generated by $.Deferred() will be used as the default parameter of this function.

8. Deploy the deferred interface on the wait object.
var dtd = $.Deferred();
    var awit = function(dtd) {
        var tasks = function() {
            alert('execution completed');
            dtd.resolve();
        }
        setTimeout(tasks, 3000);
    }
    dtd.promise(awit);
    awit.done(function() {
        alert('success');
    }).fail(function() {
        alert('failed');
    }).done(function() {
        alert('success 2');
    });
    song (dtd);
 

The key here is the line dtd.promise(wait), which is used to deploy the Deferred interface on the wait object. It is because of this line that done() and fail() can be called directly on wait.

10. Summary:

methods of deferred objects The various methods of deferred objects have been mentioned before. Here is a summary:

  (1) $.Deferred() Generates a deferred object.

  (2) deferred.done() specifies the callback function when the operation succeeds

  (3) deferred.fail() specifies the callback function when the operation fails

  (4) deferred.promise() returns a new deferred object when there is no parameter. The running state of the object cannot be changed; when the parameter is accepted, the function is to deploy the deferred interface on the parameter object.

  (5) deferred.resolve() Manually changes the running state of the deferred object to "completed", thereby triggering the done() method immediately.

  (6) deferred.reject() This method is just the opposite of deferred.resolve(), after the call, the running state of the deferred object becomes "failed", thereby triggering the fail() method immediately.

  (7) $.when() specifies callback functions for multiple operations.

In addition to these methods, the deferred object has two more important methods, which were not covered in the above tutorial.

  (8) deferred.then()

Sometimes in order to save trouble, you can write done() and fail() together, which is the then() method.

  $.when($.ajax( "/main.php" ))

  .then(successFunc, failureFunc );

If then() has two parameters, then the first parameter is the callback function of the done() method, and the second parameter is the callback method of the fail() method. If then() has only one parameter, it is equivalent to done().

  (9)

The deferred.always() method is also used to specify the callback function. Its function is that no matter whether deferred.resolve() or deferred.reject() is called, it will always be executed in the end.

  $.ajax( "test.html" )

  .always( function() { alert("Executed!");} );

 

 

Reference article: http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html

Author: Ruan Yifeng

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326187210&siteId=291194637