目录
1. 回调地狱
1.1 如何解决回调地狱的问题
2.Promise 的基本概念
2.1 基于回调函数按顺序读取文件内容编辑
3. 基于 then-fs 读取文件内容
3.1 then-fs 的基本使用
3.2 .then() 方法的特性
3.3 基于 Promise 按顺序读取文件的内容
3.4 通过 .catch 捕获错误
3.5 Promise.all() 方法
3.6 Promise.race() 方法
4. 基于 Promise 封装读文件的方法
4.1 getFile 方法的基本定义编辑
4.2 创建具体的异步操作
4.3 获取 .then 的两个实参
4.4 调用 resolve 和 reject 回调函数
5. async/await
5.1. 什么是 async/await
5.2. async/await 的基本使用
5.3. async/await 的使用注意事项
多层回调函数的相互嵌套,就形成了回调地狱。示例代码如下:
回调地狱的缺点:
为了解决回调地狱的问题,ES6(ECMAScript 2015)中新增了 Promise 的概念。
① Promise 是一个构造函数
② Promise.prototype 上包含一个.then() 方法
③ .then() 方法用来预先指定成功和失败的回调函数
由于node.js 官方提供的fs 模块仅支持以回调函数的方式读取文件,不支持 Promise 的调用方式。因此,需 要先运行如下的命令,安装then-fs 这个第三方包,从而支持我们基于 Promise 的方式读取文件的内容:
调用then-fs 提供的readFile() 方法,可以异步地读取文件的内容,它的返回值是 Promise 的实例对象。因 此可以调用.then() 方法为每个 Promise 异步操作指定成功和失败之后的回调函数。示例代码如下:
注意:上述的代码无法保证文件的读取顺序,需要做进一步的改进!
如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通
过 .then() 方法的链式调用,就解决了回调地狱的问题。
Promise 支持链式调用,从而来解决回调地狱的问题。示例代码如下:
在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype.catch 方法进行捕获和处理:
如果不希望前面的错误导致后续的 .then 无法正常执行,则可以将 .catch 的调用提前,示例代码如下:
Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then
注意:数组中 Promise 实例的顺序, 就是最终结果的顺序!
Promise.race() 方法会发起并行的 Promise 异步操作,只要任何一个异步操作完成,就立即执行下一步的.then 操作(赛跑机制)。示例代码如下:
方法的封装要求:
① 方法的名称要定义为getFile
② 方法接收一个形参fpath,表示要读取的文件的路径
③ 方法的返回值为 Promise 实例对象
注意:第 5 行代码中的new Promise() 只是创建了一个形式上的异步操作。
如果想要创建具体的异步操作,则需要在new Promise() 构造函数期间,传递一个function 函数,将具体的 异步操作定义到function 函数内部。示例代码如下:
通过.then() 指定的成功和失败的回调函数,可以在function 的形参中进行接收,示例代码如下:
Promise 异步操作的结果,可以调用resolve 或 reject 回调函数进行处理。示例代码如下:
async/await 是 ES8(ECMAScript 2017)引入的新语法,用来简化 Promise 异步操作。在 async/await 出 现之前,开发者只能通过链式.then() 的方式处理 Promise 异步操作。示例代码如下:
.then 链式调用的优点: 解决了回调地狱的问题
.then 链式调用的缺点: 代码冗余、阅读性差、 不易理解
使用 async/await 简化 Promise 异步操作的示例代码如下:
① 如果在function 中使用了 await,则 function 必须被 async 修饰
② 在 async 方法中,第一个 await 之前的代码会同步执行,await 之后的代码会异步执行