Detailed explanation of using deferred object in jQuery

  • 2021-07-02 23:31:05
  • OfStack

In versions after jquery 1.5, an deferred object, a delay object, is added to handle callback functions that occur at some point in time in the future. At the same time, the ajax method is overwritten, and now the ajax method returns an deferred object.
Let's look at the use of deferred objects.
1. Chain callback of ajax


// ajax Method returns the 1 A deferred Object, you can directly use chain writing 
$.ajax('test.json').done(function(resp){
 // done  Equivalent to success Callback, where the default parameter is success Parameters of callback 
 alert('success');
}).fail(function(){
 // fail  Equivalent to error Callback 
 alert('error');
});

You can also write multiple callbacks at the same time, which will be executed in sequence


$.ajax('test.json').done(function(resp){
 // done  Equivalent to success Callback, where the default parameter is success Parameters of callback 
 alert('success');
}).done(function(){
 // do something...
}).done(function(){
 // do something...
});

deferred object also has an then method, which is actually a method integrating done and fail. It accepts one or two parameters. If there are two parameters, the first one is the callback function of done method and the second one is the callback function of fail method. If there is only one parameter, it is the callback function of done method.


var success = function(){
 alert('success'); 
};

var error = function(){
 alert('error');
};

//  Two parameters 
$.ajax('test.json').then(success, error);

// 1 Parameters 
$.ajax('test.json').then(success);

jQuery also provides a $. when (deferreds) method to execute a callback function of one or more delayed objects. When its parameters are delayed objects, it will execute the corresponding callback function after the asynchronous execution represented by all delayed objects is completed


$.when($.ajax('test.json'), $.ajax('demo.json')) .done(function(){
 alert('success'); 
}).fail(function(){
 alert('error');
});

It is understandable that the callback in the done method will be executed only if all asynchronism succeeds, otherwise the callback in the fail method will be executed, and it is also understandable that the default number of arguments in the callback function in the done method is the same as that in the when method.
However, if only ordinary objects are passed in the when method, but not the deferred object, the callback in the done method will be executed immediately, and the default parameter of the callback function is the object itself passed in the when method.


 //  When incoming when Method when the parameters are just ordinary objects 
$.when({test: 'test'}).done(function(resp){
 console.log(resp.test); // 'test' 
}).fail(function(){
 //  Because the passed-in object is not a deferred Object, no call is made to the fail The callback in the  
}) 

When you need two or more asynchronous ends before calling the callback function, and these asynchronous ajax may need to modify the transfer mode type or the data transfer data, the code is messy and poorly readable.
So you can re-encapsulate ajax to improve code readability


var ajax = function(url, type, param){
 return $.ajax({
 url: url,
 type: type,
 data: param || {} 
 }); 
};

ajax('test.json').done(function(resp){
 alert('success');
}).fail(function(){
 alert('error');
});

Follow-up learning, missing an always () method, and the parameter is also a callback function. Unlike done and fail, the callback in always method is executed in any case.
The deferred object can not only be used in the ajax method of jquery, but also provides a series of interfaces, which greatly improves its versatility.
For example, there is such a long-time method


 function a(){
 function b(){
 alert('start');
 } 
 setTimeout(b, 3000); 
} 

If you want to execute a callback after this method, you can't use $. when (), because if the argument of $. when () is not deferred object, the callback function in done or always will be called directly.
At this time, we will use other methods of deferred objects, or the above methods, and do some rewriting


function a(){
 var def = $.Deferred(); //  Create deferred Object  
 function b(){
 alert('start');
 def.resolve(); //  Change deferred The state of the object 
 } 
 setTimeout(b, 3000); 
 return def;
}

$.when(a()).done(function(){
 alert("It's callback");
});

Under analysis 1:
1). The $. deferred () method creates an deferred object
2). def. resolve () changes the state of the deferred object. The deferred object has three states: incomplete, successful, and failed.
It has two methods, resolve () and reject (). The resolve method can change the object state to success, and the reject method can change the state to failure.
There will be problems in the above writing, and the returned deferred object can be changed externally, so an promise () method is also provided, which will return a new deferred object on the basis of deferred object. The difference is that the returned object only has an observable state, but does not have a method to change its state, which is similar to returning a read-only deferred object.
So the same example can be rewritten like this


function a(){
 var def = $.Deferred(); //  Create deferred Object  
 function b(){
 alert('start');
 def.resolve(); //  Change deferred The state of the object 
 } 
 setTimeout(b, 3000); 
 return def.promise();
}

$.when(a().reject()).done(function(){ // reject() Invalid method 
 alert("It's callback");
});

Related articles: