Article directory
1. Callback Hell?
To understand Promise, I must first understand what is callback hell? (If you understand, please skip directly to the next section)
Asynchronous functions cannot guarantee sequential execution
const fs = require('fs')
fs.readFile('./data/a.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
})
fs.readFile('./data/b.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
})
fs.readFile('./data/c.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
})
We can see from the above case that I executed the 回调地狱.js
js file three times in total. The first two executions were aaa bbb ccc, and the third time it became aaa ccc bbb
. Therefore, it can be shown that the asynchronous function of Js cannot guarantee execution. sequential
But sometimes, we need the execution sequence of these asynchronous functions to be certain.
We can read the a file, after the console prints the data result of the a file, then read the b file, and the console prints... until the c file is printed. The data content:
const fs = require('fs')
fs.readFile('./data/a.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
//控制台打印完a文件内容后,读取b文件
fs.readFile('./data/b.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
//控制台打印完b文件内容后,读取c文件
fs.readFile('./data/c.txt', 'utf-8', (err, data) => {
if (err) {
console.log('读取失败');
}
console.log(data);
})
})
})
After such nesting and re-nesting, we can obtain stable execution results. However, the execution order is determined, but such code is deeply nested, which is not convenient for our programmers to maintain later. What? You think this is fine, if you can understand it, how about you look at this?
Isn't it disgusting... = =
二、Promise
So if we don't want to use this deeply nested method, and also want to let the asynchronous function execute in order, is there any other way?
Of course! ES6 provides us with an interface called Promise, which is specially used to solve such situations as callback hell!
As the name suggests, Promise
in Chinese means “承诺”
that we should all have commitment to others scenes in our past lives, such as: You promise to your girlfriend: When she is XX, I will hold a romantic wedding for us.
And when you make a promise to your girlfriend to "hold a wedding", you are now 目前的状态
: working overtime and trying to fulfill the promise (pending); however 在未来
, there are only two possibilities (states): 1. succeeded (resolve) 2. failed So it is concluded that the pending state can only be transformed into one of resolve or reject .
So, what exactly is a Promise? How does it solve callback hell?
- Promises are essentially a constructor
- The object of the Promise instance is called the 'Promise instance, which can be used to get the result of the internal success or failure of the Promise
It is normal to not understand, please see the following example:
const fs = require('fs')
new Promise(function(resolve,reject) {
//读取文件
fs.readFile('./data/a.txt','utf-8',(err,data) => {
if(err) {
//读取失败,调用reject函数
reject(err)
}
//读取成功,调用resolve函数
resolve(data)
})
})
As can be seen from the above code, after the new promise is completed, a function will be passed to the constructor as a parameter, and inside this function, is your asynchronous code, so it seems that Promise is like a container wrapping your Asynchronous function .
const fs = require('fs')
let p1 = new Promise(function(resolve,reject) {
//读取文件
fs.readFile('./data/a.txt','utf-8',(err,data) => {
if(err) {
//读取失败,调用reject函数
reject(err)
}
//读取成功,调用resolve函数
resolve(data)
})
})
p1.then(function(data){
console.log(data); //aaa
})
We can see that Promise instantiates p1, and p1 calls the then function on its body, and the parameter function in this then function is the resolve function inside Promise.
Therefore, the data value is obtained externally.
3. Promise solves callback hell
In the above case, we learned the basic use of Promise, then we will use Promise to solve callback hell
const fs = require('fs')
const p1 = new Promise(function(resolve,reject) {
fs.readFile('./data/a.txt','utf-8',(err,data) => {
if(err) {
console.log('读取失败');
reject(err)
}
resolve(data)
})
})
const p2 = new Promise(function(resolve,reject) {
fs.readFile('./data/b.txt','utf-8',(err,data) => {
if(err) {
reject(err)
}
resolve(data)
})
})
const p3 = new Promise(function(resolve,reject) {
fs.readFile('./data/c.txt','utf-8',(err,data) => {
if(err) {
reject(err)
}
resolve(data)
})
})
p1.then(function(data) {
console.log(data);
return p2
}).then(function(data) {
console.log(data);
return p3
}).then(function(data) {
console.log(data);
})
Although the above code is a bit long, you will understand it slowly after reading it.
Because in the p1.then function, its internal function parameter returns the Promise of p2, then in the next part of .then, this function parameter is the resolve function of the previous Promise , which sounds very convoluted, right? :
Because we successfully got the data in an orderly manner.
This is called Promise chaining and solves callback hell.