“This is the third day of my participation in the November Gwen Challenge. See details of the event: The last Gwen Challenge 2021”.
The first two articles are recommended
Tear Promise from scratch, master the realization principle of Promise. (1)
Tear Promise from scratch, master the realization principle of Promise. (2)
review
As described in the previous article, we have completed the basic version of promise, as follows
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class Promise{
constructor(executor){
this.state = PENDING
this.value = undefined
this.reason = undefined
/ / store onFulfilled
this.onResolvedCallbacks = []
/ / store onRejected
this.onRejectedCallbacks = []
const resolve = (value) = > {
if (this.state === PENDING) {
this.value = value
this.state = FULFILLED
// The promise instance will call ondepressing after its state changes
this.onResolvedCallbacks.forEach(fn= > fn())
}
}
const reject = (reason) = > {
if (this.state === PENDING) {
this.reason = reason
this.state = REJECTED
// onRejected called after the promise instance state changes
this.onRejectedCallbacks.forEach(fn= > fn())
}
}
try {
// An error in the execution of the executor function will cause the Promise to fail
executor(resolve,reject)
} catch (error) {
reject(error)
}
}
then(onFulfilled, onRejected){
if (this.state === FULFILLED) {
onFulfilled(this.value)
}
if (this.state === REJECTED) {
onRejected(this.reason)
}
if (this.state === PENDING) {
// If the state of the Promise instance is not determined at this time, we need to save onFulfilled and onRejected, and then invoke the promise instance after the state changes
this.onResolvedCallbacks.push(() = > {
onFulfilled(this.value)
})
this.onRejectedCallbacks.push(() = > {
onRejected(this.reason)
})
}
}
}
Copy the code
The callback hell
Before we implement Promise’s then chain invocation mechanism, let’s take a look at callback hell and how promises can be used to solve it.
- There are two text files
age.txt
andname.txt
, contents are as follows.
- I need to read it
age.txt
Then use this path to readname.txt
The content of the code below.const fs = require('fs') // Import the file module in node fs.readFile('./age.txt'.'utf8'.function(err, data){ if(err) throw new Error(err) fs.readFile(data,'utf8'.function (err,data) { if(err) throw new Error(err) console.log(data) }) }) Copy the code
- If we had multiple files nested like this, our code would look like this, which is what we call callback hell.
fs.readFile('./age.txt'.'utf8'.function(err, data){ if(err) throw new Error(err) fs.readFile(data,'utf8'.function (err,data) { if(err) throw new Error(err) fs.readFile(data,'utf8'.function (err,data) { if(err) throw new Error(err) fs.readFile(data,'utf8'.function (err,data) { if(err) throw new Error(err) fs.readFile(data,'utf8'.function (err,data) { if(err) throw new Error(err) console.log(data) }) }) }) }) }) Copy the code
- then
Promise
How it solves callback hell as an asynchronous programming solution, let’s look at the code.- First we are going to
readFile
Method encapsulated intopromise
const readFile = (filePath) = > { return new Promise((resolve,reject) = >{ fs.readFile(filePath,'utf8'.function (err,data) { if(err) {// Failed to call reject return reject(err); } resolve(data); // Resolve was successfully called})})}Copy the code
- Use the one we encapsulated
readFile
Go to readage.txt
.name.txt
“, writing code is very friendly.
readFile('./age.txt').then(data= > { return readFile(data) }).then(data= > { console.log(data) },reason= > { console.log(reason) }) Copy the code
- We got what we wanted
- First we are going to