The interaction of web pages is becoming more and more complex, and JavaScript is also becoming more and more asynchronous operations. For example, a common ajax request requires response to operations when the request is completed. The request is usually asynchronous. During the request process, the user can perform other operations without blocking the page. This asynchronous interaction effect is quite friendly to the user. But for developers, it is very unfriendly to deal with this kind of operation in large quantities. Operations completed by asynchronous requests must be predefined in the callback function, and this function must be called after the request is completed. This nonlinear asynchronous programming method will make developers uncomfortable, and it also brings many inconveniences, increasing the coupling and complexity of the code, and the organization of the code will be very inelegant, greatly reducing the maintainability of the code. The situation is more complicated. If an operation has to wait until multiple asynchronous ajax requests are completed before it can be performed, the callback function will be nested. If several layers need to be nested, you can only ask for blessings.
Let’s take a look at the following common asynchronous functions.
The code copy is as follows:
var showMsg = function(){
setTimeout(function(){
alert( 'hello' );
}, 5000 );
};
This is usually done if you want to add a callback to the function.
The code copy is as follows:
var showMsg = function( callback ){
setTimeout(function(){
alert( 'hello' );
// Add callback here
callback();
}, 5000 );
};
If you use easy.js Promise, the method of adding callbacks will be much more elegant, as long as you need to encapsulate the original function into a promise instance.
The code copy is as follows:
var showMsg = function(){
// Construct promise instance
var promise = new E.Promise();
setTimeout(function(){
alert( 'hello' );
// Change the state of promise
promise.resolve( 'done' );
}, 5000 );
// Return to promise instance
return promise;
};
There are 3 key steps to encapsulating an ordinary function into a promise instance. The first step is to construct a promise instance inside the function. The second step is to change the state of the promise to be completed after the deployment function is executed. The third step is to return this promise instance. Each promise instance has 3 states, namely pending (not completed), resolved (completed, successful), and rejected (rejected, failed). Let’s take a look at how to add callbacks.
The code copy is as follows:
showMsg().then(function( str ){
// The callback is added here
callback( str );
});
This completely separates the callback function from the original asynchronous function, and from the perspective of code organization, it is much more elegant. resolve accepts a parameter that can easily transfer data to the callback added using the then method.
For ajax requests, easy.js directly encapsulates the ajax method into a promise object, and you can directly add the then method to call back.
The code copy is as follows:
E.ajax({
url : 'test1.php',
type: 'GET'
})
.then(function(){
// Add a callback with successful request
}, function(){
// Add a callback that failed request
});
The then method accepts 2 functions as parameters. The first function is a completed callback, and the second is a failed callback.
What if there are multiple ajax requests mentioned above? Then you have to use the when method. This method can accept multiple promise instances as parameters.
The code copy is as follows:
var requests = E.when(E.ajax({
url : 'test1.php',
type: 'GET'
}), E.ajax({
url : 'test2.php',
type: 'GET'
}));
requests.then(function( arg1, arg2 ){
console.log( 'success:' + arg1[0] + arg2[0] );
}, function( arg1, arg2 ){
console.log( 'failure:' + arg1 + arg2 );
});
The when method is to store multiple promise instances into an array, and wait until all promise instances of the array are completed before executing the completed callback. Once an instance is rejected, the rejected callback is immediately executed.
The Promise pattern is one of the specifications of CommonJS. Many mainstream JavaScript libraries have corresponding implementations, such as jQuery and Dojo, which have Deferred to implement these functions. Here I still want to complain about jQuery's Deferred. Putting aside its internal use, this should be the module with the lowest user usage rate, which has a certain relationship with its more complex usage method.