1、回调地狱问题:
nodejs的api大都是单线程异步模型,调用函数后,结果会通过回调函数来处理。
因此容易出现多层回调函数相互嵌套的现象,这种现象被称为:回调地狱。
这种代码可读性差,可维护性差。
在ES6中提供了Promise编程规范,用于解决回调地狱的问题。
2、Promise基本概念:
(1)Promise是一个构造函数
可以创建Promise的实例 const p = new Promise()
new出来的Promise实例对象,代表一个异步操作
(2)Promise.prototype上(原型链)有then()、catch()、fianlly()等方法
每一次new Promise()构造函数得到实例对象,都可以通过原型链访问then()等方法
(3)then()方法用来预先指定成功和失败的回调函数
p.then(result => {}, error => {})
result回调函数是必须指定的,error回调函数是可省略的。
3、Promise基本使用:
(1)安装thenFs包
npm install then-fs
(2)要读取的文件,files目录下有三个文件
1.txt内容为:111
2.txt内容为:222
3.txt内容为:333
(3)使用Promise读取文件代码:
import thenfs from 'then-fs' // 1、无法保证顺序 thenfs.readFile('./files/1.txt','utf-8').then(result => { console.log(result) },error => { console.log(error.message) }) thenfs.readFile('./files/2.txt','utf-8').then(result => { console.log(result) },error => { console.log(error.message) }) thenfs.readFile('./files/3.txt','utf-8').then(result => { console.log(result) },error => { console.log(error.message) })
执行结果可能是:
111 333 222
使用Promise的then方法实现:
如果上一个then()方法中返回了一个新的Promise实力对象,则可以通过下一个then()继续进行处理,通过then()方法的链式调用,就可以解决回调地狱问题:
import thenfs from 'then-fs' // 2、保证顺序,使用then()链式调用 thenfs.readFile('./files/11.txt','utf-8').then(r1 => { console.log(r1) return thenfs.readFile('./files/2.txt','utf-8') }).then( r2 => { console.log(r2) return thenfs.readFile('./files/3.txt','utf-8') }).then(r3 => { console.log(r3) }).catch(err => { console.log(err.message) })
执行结果是:
111 222 333
这个执行结果,读取文件的顺序不会改变。
4、使用ES8的async和awati简化Promise代码:
在ES8中,提供了async/await 的api,可以简化Promise的then的链式调用。
import thenfs from 'then-fs' // 3、使用async/await 简化Promise的调用 async function readFile(){ let r1 = await thenfs.readFile('./files/1.txt','utf-8') console.log(r1) let r2 = await thenfs.readFile('./files/2.txt','utf-8') console.log(r2) let r3 = await thenfs.readFile('./files/3.txt','utf-8') console.log(r3) } readFile()
执行结果为:
111 222 333
注意事项:
如果在function中使用了await关键字,那么这个function必须用async修饰。
在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行。