Promise programming mode is also called thenable, which can be understood as execution after delay. Each Promise has a unique interface called then, and when the Promise fails or succeeds, it will make a callback. It represents an operation result that may run for a long time and does not necessarily have to be completed. This pattern does not block and wait for long-term operations to complete, but returns an object that represents the promised result.
Many current JavaScript libraries (such as jQuery and Dojo, AngularJS) add this abstraction called Promise. Through these libraries, developers can use the Promise mode in actual programming.
Below we will use jQuery as an example to discuss how JavaScript libraries use the Promise mode to handle asynchronous processing, which is actually to provide fault-tolerant support through callbacks. When an operation succeeds or fails or in any case, the corresponding callback is executed, and try to handle any possible situations in a certain piece of logic.
First, let's take a look at how jQuery generally operates:
The code copy is as follows:
var $info = $("#info");
$.ajax({
url:"/echo/json/",
data: { json: JSON.stringify({"name": "someValue"}) },
type:"POST",
success: function(response)
{
$info.text(response.name);
}
});
In this example, you can see that when the setting is successful, a callback will be specified, which is a good callback method. This is not a Promise, and the official jQuery documentation no longer recommends this method (http://api.jquery.com/jQuery.ajax/#jqXHR). When the Ajax call completes, it executes the success function. Depending on the asynchronous operations used by the library, you can use various different callbacks (i.e., whether the task is successful or not, it will be called back and respond). Using Promise mode simplifies this process, asynchronous operations only require returning an object call. This Promise allows you to call a method called then and then lets you specify the number of function(s) of the callback.
Let's take a look at how jQuery builds a promise:
The code copy is as follows:
var $info = $("#info");
$.ajax({
url: "/echo/json/",
data: {
json: JSON.stringify({
"name": "someValue"
})
},
type: "POST"
})
.then(function (response) {
$info.text(response.name);
});
The jQuery ajax object implements the Promise mode by returning the xhr object, so we can call the then method. The advantage of doing this is that you can chain calls and implement independent operations, as shown below:
The code copy is as follows:
var $info = $("#info");
$.ajax({
url: "/echo/json/",
data: {
json: JSON.stringify({
"name": "someValue"
})
},
type: "POST"
})
.then(function (response) {
$info.text(response.name);
})
.then(function () {
$info.append("...More");
})
.done(function () {
$info.append("... finally!");
});
Asynchronous operations become very easy since many libraries start to use Promise mode. But if you think from the opposite perspective, what would Promise look like? One of the very important patterns is that the function can accept two functions, one is a callback when successful, and the other is a callback when failure.
The code copy is as follows:
var $info = $("#info");
$.ajax({
// Change URL to see error happen
url: "/echo/json/",
data: {
json: JSON.stringify({
"name": "someValue"
})
},
type: "POST"
})
.then(function (response) {
// success
$info.text(response.name);
},
function () {
// failure
$info.text("bad things happen to good developers");
})
.always(function () {
$info.append("... finally");
});
It should be noted that in jQuery, whether successful or failed, we will use a call to specify what we want to call.
In fact, you can also write this here, which is also the recommended method in jQuery's official document:
The code copy is as follows:
var $info = $("#info");
$.ajax({
// Change URL to see error happen
url: "/echo/json/",
data: {
json: JSON.stringify({
"name": "someValue"
})
},
type: "POST"
})
.done(function (response) {
// success
$info.text(response.name);
}).fail(function () {
// failure
$info.text("bad things happen to good developers");
})
.always(function () {
$info.append("... finally");
});
Let’s take a look at how AngularJS uses the Promise mode:
The code copy is as follows:
var m = angular.module("myApp", []);
m.factory("dataService", function ($q) {
function _callMe() {
var d = $q.defer();
setTimeout(function () {
d.resolve();
//defer.reject();
}, 100);
return d.promise;
}
return {
callMe: _callMe
};
});
function myCtrl($scope, dataService) {
$scope.name = "None";
$scope.isBusy = true;
dataService.callMe()
.then(function () {
// Successful
$scope.name = "success";
},
function () {
// failure
$scope.name = "failure";
})
.then(function () {
// Like a Finally Clause
$scope.isBusy = false;
});
}
You can try these examples in JSFiddle and see what effects will be produced. Using Promise to operate asynchronous is a very simple way, and it can also simplify your code. It is indeed a good way to kill two birds with one stone.
For more introductions and examples about Promise, you can go to the official website (http://www.promisejs.org/).