什么是promise?
首先我们来看一个小案例
data文件夹下是三个文件,我们要写一个代码分别依次读取三个文件,使得按照 abc 的顺序输出
![在这里插入图片描述](http://image109.360doc.com/DownloadImg/2022/01/1412/237783079_1_20220114121743929_wm)
无法保证输出顺序的代码
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
// 抛出异常
// 1. 阻止程序的执行
// 2. 把错误消息打印到控制台
throw err
}
console.log(data)
})
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
throw err
}
console.log(data)
})
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
throw err
}
console.log(data)
})
这样写无法保证文件内容输出的顺序,应为读取文件函数为异步函数,那么如何解决这样的问题呢?
首先我们可以想到用嵌套的方法,后输出的放在代码最内部,先输出的放在代码最外部,但是这样一层层的嵌套使用,几个异步函数还好,当函数很多时就会显得非常不美观,而且不容易修改,还会产生一系列问题,这就产生了下面的回调地狱问题
回调地狱(callback hell)
下图代码就是回调地狱的一种,是不是像冲击波一样冲击着广大程序员的幼小的心灵。(豪油根~~~)
![在这里插入图片描述](http://image109.360doc.com/DownloadImg/2022/01/1412/237783079_2_20220114121744272_wm)
var fs = require('fs')
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
throw err
}
console.log(data)
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
throw err
}
console.log(data)
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
throw err
}
console.log(data)
})
})
})
接下来我们用 ES6新增的Promise来解决回调地狱问题
Promise解决
当 p1 读取成功的时候
当前函数中 return 的结果就可以在后面的 then 中 function 接收到
- 当你 return 123 后面就接收到 123
- return 'hello’ 后面就接收到 'hello’
- 没有 return 后面收到的就是 undefined
上面那些 return 的数据其实是没什么der用的
真正有用的是:我们可以 return 一个 Promise 对象
当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
var fs = require('fs')
var p1 = new Promise(function (resolve, reject) {
fs.readFile('./data/a.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p2 = new Promise(function (resolve, reject) {
fs.readFile('./data/b.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
var p3 = new Promise(function (resolve, reject) {
fs.readFile('./data/c.txt', 'utf8', function (err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
p1
.then(function (data) {
console.log(data)
return p2
}, function (err) {
console.log('读取文件失败了', err)
})
.then(function (data) {
console.log(data)
return p3
})
.then(function (data) {
console.log(data)
console.log('end')
})