Using the $.Deferred object in jQuery as an example how do promise objects handle asynchronous problems

  • 2020-10-23 20:53:32
  • OfStack

Promises, an abstraction that makes code asynchronous behavior more elegant, is likely the next programming paradigm for JavaScript, where an Promise represents the result of a task, whether or not the task is completed.

Native Promise objects, which follow the Promise/A+ standard, are available in 1 modern browsers. In jQuery1.5+, $.Deferred (which can be converted to promise objects) is provided. promise objects are also provided in many well-known frameworks. The promise object is already an important pattern in javascript, and the elegance with which it solves asynchronous problems is exactly what javascript needs. Take the $.Deferred object in jQuery as an example to see how the promise object handles asynchrony in 1. For the $.Deferred object, please visit the jQuery website, and I won't go into details here.

1. Encapsulate asynchronous operations

First, let's take loading pictures as an example and look at the following code:


// Load image function 
var loadImg = function(url){
  var img = new Image() , deferred = $.Deferred() ;
 img.src = url ;
 img.onload = function(){
  // Success triggers deferred.resolve
    deferred.resolve( this ) ;
 } ;
 img.onerror = function(e){
    // Failure triggers deferred.reject
  deferred.reject( e );
 } ;
  // return promise object 
 return deferred.promise() ;
} ;
// Request the picture 
var request = loadImg('http://r2.ykimg.com/0515000054AFFC2D6737B343930AFAD6') ;
// The request is successful 
request.done(function(img){
  //code
}) ;
// Multiple callbacks can be registered, and when the request is successful, they are executed in the order of registration, fail and always It also has this property 
request.done(function(img){
  // code
});
// The request failed 
request.fail(function(){
  // code
}) ;
// The request is completed 
request.always(function(){
  //code
});

In the above code, I encapsulate the image loading operations, delegate them to $.Deferred, and finally generate an promise return. With this approach, it is cleaner and clearer than with an exposed callback. Another, more important reason for doing this is the connection to promise.

2. Connection to promise

Let's take the code loaded in the picture above as an example to see how to make the connection of promise. See the following code:


var request = loadImg('http://b1.hucdn.com/upload/item/1411/13/89613257775992_800x800.jpg') ;
request.done(function(img){
  //code
}) ;
//request Connect the other promise And then come back promise
var request3 = request.then(function(img){
  //request When executed successfully   The connection request1
  var request1 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;
  return request1 ;
},function(e){
  //request When execution fails   The connection request2
  var request2 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ;
  return request2 ;
});
//request Perform and request1 or request2 Successful execution 
request3.done(function(done){
  //code
}) ;

The promise object provides the method for then, which accepts two callbacks, onResolve and onReject, and returns promise in the callback to complete the connection between promise. In this way, asynchronous operations can be executed serially.

At the same time, jQuery also provides another way to connect. See the code:


var request = loadImg('http://b1.hucdn.com/upload/item/1412/23/48188827139381_800x800.jpg') ;
var request1 = loadImg('http://b1.hucdn.com/upload/item/1412/06/50258594673502_800x800.jpg') ;
// through $.when The connection promise
var request2 = $.when(request,request1) ;
request2.done(function(img,img){
  //code
}) ;

jQuery provides the function $.when, which takes n's promise objects as arguments and concatenates the results of promise's execution up to 1. In this way, multiple asynchronous operations can be executed in parallel.

3. The End

The code here takes loading images as an example, and the same approach can be applied to other asynchronous operations. For example, in jQuery, $.ajax, $.fn.animate, call them and return promise. On the node side, it is also possible to encapsulate 1 asynchronous operation (read database, read file, etc.) into promise. In turn, multiple promise are merged so that they are executed sequentially or in parallel.

Attached: deferred object

In addition to being used to transform promise objects, deferred is a useful object in its own right. In addition to providing methods and properties like the promise object, it also has the notify and progress functions, which are very useful for implementing progress bars and waterfall flows.

When implementing a progress bar, the resolve and done functions can be used to define the trigger time and trigger logic when the progress bar reads 100%, and the notify and progress functions can be used to define the trigger time and trigger logic when the progress bar reads 100%. The reject and fail functions can be used to define the trigger timing and trigger logic when a progress read fails.

When implementing waterfall flow, the resolve and done functions can be used to define the trigger time and trigger logic when all the data has been loaded onto the page, and the notify and progress functions can be used to define the trigger time and trigger logic for the waterfall flow to read the next page.


Related articles: