1.回调地狱
多层回调函数的相互嵌套,就形成了回调地狱。示例代码如下:
回调地狱的缺点:
- 代码耦合性太强,牵一发而动全身,难以维护
- 大量冗余的代码相互嵌套,代码的可读性变差
1.1 Promise 的基本概念
- Promise是一个构造函数
我们可以创建Promise的实例const p = new Promise()
new出来的Promise 实例对象,代表一个异步操作 - Promise.prototype 上包含一个.then()方法
每一次new Promise()构造函数得到的实例对象,都可以通过原型链的方式访问到.then()方法,例如p.then()
- .then()方法用来预先指定成功和失败的回调函数
p.then(成功的回调函数,失败的回调函数)
p.then(result => { }, error => { ))
调用.then()方法时,成功的回调函数是必选的、失败的回调函数是可选的
2.基于then-fs 读取文件内容
由于node.js官方提供的fs模块仅支持以回调函数的方式加粗样式读取文件,不支持Promise的调用方式。因此,需要先运行如下的命令,安装then-fs这个第三方包,从而支持我们基于Pfomise的方式读取文件的内容:
npm i then-fs
2.1 then-fs的基本使用
调用then-fs 提供的readFile()方法,可以异步地读取文件的内容,它的返回值是Promise的实例对象。因此可以调用.then()方法为每个Promise 异步操作指定成功和失败之后的回调函数。示例代码如下:
import thenFs from 'then-fs'
thenFs.readFile('./files/1.txt', 'utf8').then((r1) => {console.log(r1)})
thenFs.readFile('./files/2.txt', 'utf8').then((r2) => {console.log(r2)})
thenFs.readFile('./files/3.txt', 'utf8').then((r3) => {console.log(r3)})
注意:上述的代码无法保证文件的读取顺序,需要做进一步的改进!
2.2 基于Promise按顺序读取文件的内容
Promise支持链式调用,从而来解决回调地狱的问题。
在Promise 的链式操作中如果发生了错误,可以使用Promise.prototype.catch方法进行捕获和处理:
import thenFs from 'then-fs'
thenFs
.readFile('./files/11.txt', 'utf8')
.catch((err) => {
console.log(err.message)
})
.then((r1) => {
console.log(r1)
return thenFs.readFile('./files/2.txt', 'utf8')
})
.then((r2) => {
console.log(r2)
return thenFs.readFile('./files/3.txt', 'utf8')
})
.then((r3) => {
console.log(r3)
})
2.3 Promise.all()方法
Promise.all()方法会发起并行的Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的.then操作(等待机制)。示例代码如下:
2.4 Promise.race()方法
Promise.race()方法会发起并行的Promise异步操作,只要任何一个异步操作完成,就立即执行下一步的.then操作(赛跑机制)。示例代码如下: