Original website: JS--Promise -- use / tutorial / example_ CSDN blog
brief introduction
explain
This article introduces Promise of JavaScript with examples. It is a new feature in ES6.
Purpose of Promise
- Used for asynchronous programming
- Solve callback hell (also known as the pyramid of doom)
- If the asynchronous callback is performed again in the asynchronous call, it will be difficult to maintain if there are too many nested levels.
Three states of Promise
- pending: wait (initial state)
- It becomes "fully" when resolve is called.
- It becomes "rejected" when reject is called.
- Fully: completed
- Rejected: failed. (rejected)
After the state changes to resolved or rejected, it will not change again. These two states are called "set".
Usage introduction
sketch
Promise has these contents: constructors, object instance methods, and static methods
- 1 constructor: new Promise
- Instance method of 3 objects: then and catch and finally (not commonly used)
- 5 static methods: promise all,Promise.allSettled,Promise.race,Promise.resolve,Promise.reject
then and catch
. The catch(f) call is A complete simulation of then(null, f), which is just a short form.
then and catch only need one. then is generally used because it can handle both completed and rejected, while catch can only handle rejected.
In the following program, reject will be carried out, and the subsequent then will be executed catch will not execute, finally will execute.
let promise = new Promise(function (resolve, reject) { setTimeout(() => { reject("Scheduled task results(reject)"); }, 1000); }); promise .then( result => console.log("success(then): " + result), error => console.log("error(then): " + error) ) .catch( error => console.log("error(catch): " + error) ) .finally( () => console.log("End of operation(finally)") );
result
error(then): Scheduled task results(reject) End of operation(finally)
resolve and reject
resolve method:
Mark this status as fully completed through the {resolve(data) in the callback, and then proceed to the next step} then ((data) = > {/ / do something}). The data in resolve is the data you want to pass in then.
reject method:
Mark the status as rejected through the {reject(data) in the callback, and then proceed to the next step} then ((data1, data2) = > {/ / do something}). The data in resolve is the data2 you want to pass in then.
The executor can only call one resolve or reject, and all other resolve and reject calls will be ignored:
let promise = new Promise(function(resolve, reject) { resolve("done"); reject(new Error("...")); // Ignored setTimeout(() => resolve("...")); // Ignored });
Example (asynchronous programming)
Example 1: resolve (successful)
let promise = new Promise(function (resolve, reject) { setTimeout(() => { resolve("Scheduled task results(resolve)"); }, 1000); }); promise .then( result => console.log("success(then): " + result), error => console.log("error(then): " + error) ) .finally( () => console.log("End of operation(finally)") );
result
success(then): Scheduled task results(resolve) End of operation(finally)
Example 2: reject
let promise = new Promise(function (resolve, reject) { setTimeout(() => { reject("Scheduled task results(reject)"); }, 1000); }); promise .then( result => console.log("success(then): " + result), error => console.log("error(then): " + error) ) .finally( () => console.log("End of operation(finally)") );
result
error(then): Scheduled task results(reject) End of operation(finally)
Example: resolving callback hell
What is callback region?
If the asynchronous callback is performed again in the asynchronous call, it will be difficult to maintain if there are too many nested levels. This is hell.
For example: use ajax to request URL, then request url1 after success, and then request url2 after success. The code will look like the following:
ajax(url, () => { // processing logic ajax(url1, () => { // processing logic ajax(url2, () => { // processing logic }) }) })
In order to facilitate the demonstration, the department adopts the way of scheduled tasks.
Requirement: output every 1 second, first, second, third and end respectively.
Recurring callback hell
let fn = function (order, callback) { setTimeout(function () { console.log(order); callback(); }, 1000); } fn("first", function () { fn("second", function () { fn("third", function () { console.log("end"); }); }); });
result
first second third end
Promise resolve callback hell
let fn = function (order) { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(order); //After the asynchronous operation is completed, the resolve() function is executed resolve(); }, 1000); }); } fn("first") .then(function () { //Still return a Promise object return fn("second"); }) .then(function () { return fn("third"); }) .then(function () { console.log('end'); })
result
first second third end
async + await resolve callback hell
async + await is a further encapsulation of promise.
let fnTimeOut = function (order) { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(order); //After the asynchronous operation is completed, the resolve() function is executed resolve(); }, 1000); } ); }; async function fn() { let first = await fnTimeOut("first"); let second = await fnTimeOut("second"); let third = await fnTimeOut("third"); console.log("end"); } fn();
result
first second third end