Basic use of Promise

1.1 Introduction to Promise

Promise is a solution to asynchronous programming that makes more sense and is more powerful than traditional solutions — callback functions and events. It was first proposed and implemented by the community, and ES6 has written it into the language standard, unifying usage, and providing Promise objects natively.

A Promise is simply a container that holds the result of an event (usually an asynchronous operation) that will end in the future. Syntactically, a Promise is an object from which to get messages for asynchronous operations. Promise provides a uniform API, and all kinds of asynchronous operations can be handled in the same way.

Promise objects have two characteristics.

(1) The state of the object is not affected by the outside world. The Promise object represents an asynchronous operation with three states: Pending, fulfilled and Rejected. Only the result of an asynchronous operation can determine the current state, and no other operation can change the state. That’s where the name “Promise” comes from. Its English name means “Promise,” indicating that nothing else can change it.

(2) Once the state changes, it will never change again, and this result can be obtained at any time. There are only two possibilities for the state of the Promise object to change from pending to depressing and from pending to Rejected. As long as these two things are happening the state is fixed, it’s not going to change, it’s going to stay the same and that’s called resolved. If the change has already occurred, you can add a callback to the Promise object and get the same result immediately. This is quite different from an Event, which has the characteristic that if you miss it and listen again, you will not get the result.

1.2 basic use of Promise

The new Promise is a container that can hold both asynchronous and synchronous actions

const fs = require("fs"); const path = require("path"); let filePath = path.join(__dirname, "files", "3.txt"); // Async operation can succeed or fail // resolve, the function executed on success // reject, the second parameter, Let p1 = new Promise((resolve, reject)=>{console.log(" console.log "); Fs. readFile(filePath," utF-8 ",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1); resolve(data1); // call the second function after p1.then})}); Then ((data1)=>{console.log(" read successfully ", data1); },(error1)=>{console.log(" read failed ", error1); });Copy the code

1.3 Features of then chain invocation of Promise

Chain call features: If the first then parameter receives a promise, the next then parameter receives a promise. If the first then parameter receives a promise, the next THEN parameter receives a promise. It’s the actual argument inside the Promise object when resolve is called

const fs = require("fs"); const path = require("path"); let filePath = path.join(__dirname, "files", "3.txt"); // The new Promise is a container that can hold asynchronous or synchronous operations. // The asynchronous operation may succeed or fail. // The first parameter resolve, the function to execute on success, // the second parameter reject, Let p1 = new Promise((resolve, reject)=>{//1, sync // console.log(" sync "); Fs. readFile(filePath," utF-8 ",(error1, Data1)=>{if(error1){reject(error1)} resolve(' resolve ')}); Then ((data1)=>{return p1},(error1)=>{console.log(" read failed ", error1); return error1 }).then((data)=>{ console.log(data); // "resolve ("resolve parameter ")});Copy the code

Second, use promise to implement the previous file read case

2.1 basic version

// const fs = require("fs"); const path = require("path"); let filePath1 = path.join(__dirname, "files", "1.txt"); let filePath2 = path.join(__dirname, "files", "2.txt"); let filePath3 = path.join(__dirname, "files", "3.txt"); Let p1 = new Promise((resolve, reject)=>{//1; Fs. readFile(filePath1," UTF-8 ",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1)})}); Let p2 = new Promise((resolve, reject)=>{//1, resolve // console.log(" sync "); Fs. readFile(filePath2," UTF-8 ",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1)})}); Let p3 = new Promise((resolve, reject)=>{//1, "// console.log "); Fs. readFile(filePath3," UTF-8 ",(error1, Data1)=>{if(error1){reject(error1)} resolve(data1)})}); let str1 = ""; p1.then((data)=>{ str1+=data; Return p2},(error1)=>{console.log(" failed to read file 1 ", error1); return error1 }).then((data)=>{ str1+=data; return p3; }).then((data)=>{ str1+=data; console.log(str1); });Copy the code

2.2. Package the functional version

const fs = require("fs"); const path = require("path"); let filePath1 = path.join(__dirname, "files", "1.txt"); let filePath2 = path.join(__dirname, "files", "2.txt"); let filePath3 = path.join(__dirname, "files", "3.txt"); function readFilePromise(filePath){ return new Promise((resolve, reject)=>{ fs.readFile(filePath,"utf-8",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1)})}); } let str1 = ""; readFilePromise(filePath1).then((data)=>{ str1+=data; Return readFilePromise(filePath2)},(error1)=>{console.log(" Failed to read file 1 ", error1); return error1 }).then((data)=>{ str1+=data; return readFilePromise(filePath3); }).then((data)=>{ str1+=data; console.log(str1); });Copy the code

2.3 util version

Node has a util utility module with a promisify method that encapsulates a function that returns a promise object.

Documentation website: nodejs.cn/api/util.ht…

Pass in a function that follows the common error-first callback style (that is, with (err, value) =>… Callback as the last argument) and returns a version that returns the promise.

let readFilePromise = util.promisify(fs.readFile); // function readFilePromise(filePath){// return new Promise((resolve, resolve)) Reject) = > {/ / / / fs. ReadFile (filePath, "utf-8", (error1, data1) = > {/ / if (error1) {/ / / / fail to do / / reject (error1); / /} / / / / read after doing / / resolve (data1) / / / /}})); Promisify (fs.readfile) gets a promise objectCopy the code

Complete code:

const fs = require("fs"); const path = require("path"); const util = require("util"); let filePath1 = path.join(__dirname, "files", "1.txt"); let filePath2 = path.join(__dirname, "files", "2.txt"); let filePath3 = path.join(__dirname, "files", "3.txt"); let filePath4 = path.join(__dirname, "files", "data.txt"); let readFilePromise = util.promisify(fs.readFile); let writeFilePromise = util.promisify(fs.writeFile); let str1 = ""; readFilePromise(filePath1).then((data)=>{ str1+=data; Return readFilePromise(filePath2)},(error1)=>{console.log(" Failed to read file 1 ", error1); return error1 }).then((data)=>{ str1+=data; return readFilePromise(filePath3); }).then((data)=>{ str1+=data; console.log(str1); writeFilePromise(filePath4, str1); });Copy the code

2.4. All version

const fs = require("fs"); const path = require("path"); const util = require("util"); let filePath1 = path.join(__dirname, "files", "1.txt"); let filePath2 = path.join(__dirname, "files", "2.txt"); let filePath3 = path.join(__dirname, "files", "3.txt"); let filePath4 = path.join(__dirname, "files", "data.txt"); let readFilePromise = util.promisify(fs.readFile); Let writeFilePromise = util.promisify(fs.writefile); // Let writeFilePromise = util.promisify(fs.writefile); Promise.all([readFilePromise(filePath1,"utf-8"), readFilePromise(filePath2,"utf-8"),readFilePromise(filePath3,"utf-8")]).then((data)=>{ let str1 = data.join(""); writeFilePromise(filePath4,str1); }). Catch ((error)=>{console.log(error); });Copy the code

2.5. Async +await version

const fs = require("fs");
const path = require("path");
const util = require("util");
​
let filePath1 = path.join(__dirname, "files", "1.txt");
let filePath2 = path.join(__dirname, "files", "2.txt");
let filePath3 = path.join(__dirname, "files", "3.txt");
let filePath4 = path.join(__dirname, "files", "data.txt");
​
let readFile = util.promisify(fs.readFile);
let writeFile = util.promisify(fs.writeFile);
​
async function func() {
    let data1 = await readFile(filePath1, "utf-8");
    let data2 = await readFile(filePath2, "utf-8");
    let data3 = await readFile(filePath3, "utf-8");
​
    console.log(data1+data2+data3);
​
    writeFile(filePath4, data1+data2+data3)
}
​
func();
Copy the code

Other common methods of Promise

3.1. Promise objects catch() and finally() methods

Then ((data1)=>{console.log(" promise success ", data1); },(error1)=>{console.log(" promise failed ", error1); }); / / write p1. Then ((data1) = > {the console. The log (" commitment to success ", data1); }). The catch ((error1) = > {the console. The log (" commitment to failure, "error1); = > {}). The finally ((). The console log (" commitment to success and failure will execute the code "); });Copy the code

3.2 the All () method of the Promise class

Arguments: is an array whose elements are Promise instance objects. The first then callback is executed only if all of the promises in the array succeed

const fs = require("fs"); const path = require("path"); let filePath1 = path.join(__dirname, "files", "1.txt"); let filePath2 = path.join(__dirname, "files", "2.txt"); Let p1 = new Promise((resolve, reject)=>{//1; Fs. readFile(filePath1," UTF-8 ",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1)})}); Let p2 = new Promise((resolve, reject)=>{//1, resolve // console.log(" sync "); Fs. readFile(filePath2," UTF-8 ",(error1, Data1)=>{if(error1){// Reject (error1); Resolve (data1)})}); Promise.all([p1,p2]). Then ((data)=>{console.log(data); // [' I ', 'love'] console.log(data.join("")); // I love}). Catch ((error)=>{console.log(error); });Copy the code

3.3. Race () method of the Promise class

The first callback argument to then will be executed only if any of the Promise elements in the array succeed: Is an array whose elements are Promise instance objects. Only if any of the promises in the array succeed will the first then callback be executed

let p1 = new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log("p1"); }, 1000)}); let p2 = new Promise((resolve, reject)=>{ setTimeout(()=>{ console.log("p2"); }, 2000)}); Promise.race([p1,p2]).then((data)=>{// p1,p2 console.log(data); });Copy the code

Async +await

4.1 basic structure of async+await

Async function func() {let data1 = await promise 1; Let data2 = await promise object 2; Let data3 = await promise object 3; } // Execute asynchronous function object 1 first, then execute asynchronous function object 2, then execute asynchronous function object 3Copy the code

Case as 2.5

4.2 matters needing attention

  1. “Await” is just a basic datatype that will be wrapped as a Promise object
async function func() { let data1 = await 123; //1. Await the basic datatype and wrap it as a Promise object.  new Promise((resolve,reject)=>{resolve(123)}) console.log("data1:", data1); //data1: 123 return data1 // return await data1 } let a = func(); console.log(a); // Promise { <pending> } a.then((data)=>{ console.log(data); //123 receives the result of the return value of the Promise object});Copy the code
  1. If await is followed by a Promise object, resolve is returned
  2. An async function synchronizes asynchronous code
async function func() { console.log("start-------"); let data1 = await readFile(filePath1, "utf-8"); console.log("end-----------"); let data2 = await readFile(filePath2, "utf-8"); let data3 = await readFile(filePath3, "utf-8"); console.log(data1+data2+data3); } console.log("start"); func(); console.log("end"); / / the output in the order: / / start / / start -- -- -- -- -- -- -- / / end / / end -- -- -- -- -- -- -- -- -- -- -Copy the code
  1. Error handling (external handling)

  2. Error handling (external handling)

async function func() {
    let data1 = await readFile(filePath1, "utf-8");
    let data2 = await readFile(filePath2, "utf-8");
    let data3 = await readFile(filePath3, "utf-8");
​
    console.log(data1+data2+data3);
​
    // writeFile(filePath4, data1+data2+data3)
}
​
func().catch( error => {
    console.log(error);
} ).finally(()=>{
    console.log("finally");
});
Copy the code
  1. Error handling (internal handling)
async function func() {
    try{
        let data1 = await readFile(filePath1, "utf-8");
        let data2 = await readFile(filePath2, "utf-8");
        let data3 = await readFile(filePath3, "utf-8");
    }
    catch (error) {
        console.log(error);
        return
    }
    finally {
        console.log("finally");
    }
​
    console.log("end");
}
​
func();
Copy the code