Translation: JavaScript Promises and AngularJS $q Service
Original: http://www.webdeveasy.com/javascript-promises-and-angularjs-q-service/
Original date: September 30, 2014
A promise (delay) is a simple and powerful way to handle asynchronous development. CommonJS Wikipedia lists the implementation proposals for several promise models. Angularjs's own promise implementation method is inspired by the method Kris Kowal's Q. In this article I will introduce promises, its purpose and how to develop tutorials through the Promise service of Angularjs $q .
Promise (delay) Purpose
in JavaScript, asynchronous methods typically implement successful or failed processing by invoking a callback method. For example, the browser's geo-location API, when acquiring geographic coordinates, requires a successful or failed callback method.
function success(position) {
var coords = position.coords;
console.log(‘Your current position is ‘ + coords.latitude + ‘ X ‘ + coords.longitude);
}
function error(err) {
console.warn(‘ERROR(‘ + err.code + ‘): ‘ + err.message);
}
navigator.geolocation.getCurrentPosition(success, error);
Another example is the XHR request (Ajax request), which has a onreadystatechange callback method that is invoked when the readystate changes.
var xhr = new window.XMLHttpRequest();
xhr.open(‘GET‘, ‘http://www.webdeveasy.com‘, true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log(‘Success‘);
}
}
};
xhr.send();
There are many other asynchronous examples in JavaScript, which are discussed below to run multiple asynchronous methods that are troublesome .
serial (Endless Pyramid)
Suppose now that n async methods need to run serially:, async1(success, failure)async2(success, failure), ...,asyncN(success, failure),一个接一个直到成功,每个方法都有成功和失败的回调,那么代码就是这样:
async1(function() {
async2(function() {
async3(function() {
async4(function() {
....
....
....
asyncN(null, null);
....
....
....
}, null);
}, null);
}, null);
}, null);
This is the famous callback pyramid (callback Pyramid of Doom). Although there is a better way of writing (separating the callback stream into a function), it is still difficult to read and maintain.
Parallel
Suppose we have n async methods,,async1(success, failure)async2(success, failure)...,asyncN(success, failure)we need to let them run in parallel, and then pop a message at the end. Each method has a successful and failed callback, so this is the code:
var counter = N;
function success() {
counter --;
if (counter === 0) {
alert(‘done!‘);
}
}
async1(success);
async2(success);
....
....
asyncN(success);
We declare a variable counter, Let it have a value of N, whenever a method succeeds, subtract one, and then detect whether it is zero, that is, whether to execute to the last. This approach is cumbersome and detrimental to maintenance, especially when each asynchronous method has parameters to be passed to the success () method, so we also save the results of each run.
In the above two examples, during an asynchronous operation, we have to specify a successful callback. That is, when we use callbacks, the continuation of an asynchronous operation requires a reference, but the next step of the operation may be unrelated to itself. This results in tightly coupled modules and services that are difficult to reuse and test.
Translation: JavaScript Promises and AngularJS $q Service