Synchronous programming is generally easy to debug and maintain, however, asynchronous programming generally provides better performance and greater flexibility. The biggest feature of asynchronous is that there is no need to wait. "Promises" gradually became the most important part of JavaScript, and a large number of new APIs have begun to implement the promise principle. Let's take a look at what promise is, and its API and usage!
Promises status
The XMLHttpRequest API is asynchronous, but it does not use the promise API. But there are many native javascript APIs that use promise:
*Battery API
*fetch API (A replacement for XHR)
*ServiceWorker API
Promises will only become more popular and common in the future, and it is very important that all front-end developers will use it. Another thing worth noting is that Node.js is a Promises-based platform (it's obvious that Promise is a core feature of it).
The usage of Promises is simpler than you think - if you used to use setTimeout to control asynchronous tasks!
Basic usage of Promise
The new Promise() constructor can be used in traditional asynchronous tasks, just like the previous usage of setTimeout and XMLHttpRequest. A new Promise is generated using the new keyword. At the same time, this Promises provides resolve and reject functions to allow us to perform callback operations:
var p = new Promise(function(resolve, reject) { // Do an async task async task and then... if(/* good condition */) { resolve('Success!'); } else { reject('Failure!'); }});p.then(function() { /* do something with the result */}).catch(function() { /* error */})Programmers can manually call resolve and reject functions within the callback function according to the execution situation. Here is a more realistic example that converts an XMLHttpRequest call to a Promises-based task:
// From Jake Archibald's Promises and Back:// http://www.html5rocks.com/en/tutorials/es6/promises/#toc-promising-xmlhttprequestfunction get(url) { // Return a new promise. return new Promise(function(resolve, reject) { // Do the usual XHR stuff var req = new XMLHttpRequest(); req.open('GET', url); req.onload = function() { // This is called even on 404 etc // so check the status if (req.status == 200) { // Resolve the promise with the response text resolve(req.response); } else { // Otherwise reject with the status text // which will hopefully be a meaningful error reject(Error(req.statusText)); } }; // Handle network errors req.onerror = function() { reject(Error("Network Error")); }; // Make the request req.send(); });}// Use it!get('story.json').then(function(response) { console.log("Success!", response);}, function(error) { console.error("Failed!", error);});Promise.resolve() and Promise.reject() can be called directly. Sometimes, when we determine that promise does not need to be executed, we do not need to use new to create a Promise object, but can directly call Promise.resolve() and Promise.reject(). for example:
var userCache = {};function getUserDetail(username) { // In both cases, cached or not, a promise will be returned if (userCache[username]) { // Return a promise without the "new" keyword return Promise.resolve(userCache[username]); } // Use the fetch API to get the information // fetch returns a promise return fetch('users/' + username + '.json') .then(function(result) { userCache[username] = result; return result; }) .catch(function() { throw new Error('Could not find user: ' + username); });}Because promise will definitely return, we can use the then and catch methods to handle the return value!
Then method
All promise object instances have an then method, which is used to interact with this promise. First, the then method will call the resolve() function by default:
new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve(10); }, 3000);}).then(function(result) { console.log(result);});// From the console:// 10Then the triggering time of the callback action is that promise is executed. We can also perform callback operations in concatenated the then method:
new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve(10); }, 3000);}).then(function(num) { console.log('first then: ', num); return num * 2; }).then(function(num) { console.log('last then: ', num); return num * 2; }).then(function(num) { console.log('last then: ', num);});// From the console:// first then: 10// second then: 20// last then: 40You will find that each then call will take the return value of the previous then call as a parameter.
If a promise has been executed and the single then is called again, the callback action will be executed again. If the reject callback function is executed in this promise, and the then method is called, the callback function will not be executed.
catch method
catch When a promise is rejected (rejected), the catch method will be executed:
new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { reject('Done!'); }, 3000);}).then(function(e) { console.log('done', e); }).catch(function(e) { console.log('catch: ', e); });// From the console:// 'catch: Done!'Usually we handle the result of execution failure in the reject method, and execute the exception result in the catch:
reject(Error('Data could not be found'));
Promise.all method
There is often a scenario when we call asynchronously: we need to call multiple asynchronous operations at the same time, but we hope that we will only perform the response operation after all operations are completed - this is the role of Promise.all. The Promise.all method can receive multiple promises as parameters, in the form of an array, and the callback function will be called after all these promises are successfully executed.
Promise.all([promise1, promise2]).then(function(results) { // Both promises resolved}).catch(function(error) { // One or more promises was rejected});A good example of using Promise.all is to perform multiple AJAX operations (via fetch) calls:
var request1 = fetch('/users.json');var request2 = fetch('/articles.json');Promise.all([request1, request2]).then(function(results) { // Both promises done!});We can also perform a mix of fetch and battery state APIs, because they all return promises:
Promise.all([fetch('/users.json'), navigator.getBattery()]).then(function(results) { // Both promises done!});Once the reject function is called in the promise, the execution is rejected and cannot be completed normally, the situation will be a bit complicated. Once the promise is rejected, the catch method will catch the first executed reject function:
var req1 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('First!'); }, 4000);});var req2 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { reject('Second!'); }, 3000);});Promise.all([req1, req2]).then(function(results) { console.log('Then: ', one);}).catch(function(err) { console.log('Catch: ', err);});// From the console:// Catch: Second!Promise.all is a very important interface and will play an important role in many newly born promise APIs.
Promise.race
Promise.race is an interesting function - it does not wait for all promises to be resolved or rejected, but in all promises, it will fire as long as one execution ends:
var req1 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('First!'); }, 8000);});var req2 = new Promise(function(resolve, reject) { // A mock async action using setTimeout setTimeout(function() { resolve('Second!'); }, 3000);});Promise.race([req1, req2]).then(function(one) { console.log('Then: ', one);}).catch(function(one, two) { console.log('Catch: ', one);});// From the console:// Then: Second!A useful scenario is to download resources from multiple mirror servers. Once one returns, the other returns are not processed.
Learn to use Promises
Promises has been a very hot topic in the past few years, and it has even been pulled from JavaScript to become a language architecture. I believe we will soon see more and more JavaScript APIs that will use promise-based patterns.
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.