一、promise基本概念
1.1 回调问题
在平常敲代码中经常会遇到多层回调函数的相互嵌套问题。如下:
这会使得代码耦合性太强,牵一发而动全身,难以维护 。大量冗余的代码相互嵌套,代码的可读性变差。
1.2 如何解决回调问题
为了解决回调过深的问题, ES6 (ECMAScript 2015)中新增了 Promise 的概念。
1.3 Promise 的基本概念
Promise 是一个构造函数
我们可以创建 Promise 的实例 const p = new Promise()
new 出来的 Promise 实例对象, 代表一个异步操作
二、Promise.then()
Promise.prototype 上包含一个 .then() 方法
每一次 new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到 .then() 方法,例如 p.then()。
then() 方法用来预先指定成功和失败的回调函数
then()方法是异步执行。意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。
a. p.then(成功的回调函数,失败的回调函数)
b. p.then(result => { }, error => { })
c. 调用 .then() 方法时,成功的回调函数是必选的、失败的回调函数是可选的
一个简单的读取文件例子:
thenFs.readFile('./files/1.txt', 'utf8').then((r1) => { console.log(r1) })//111
三、Promise链式调用
3.1 .then()方法特性
promise支持链式调用。如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通 过 .then() 方法的链式调用,就解决了回调过深的问题。
就例如想要按顺序读取文件内容:
import thenFs from "then-fs";
thenFs.readFile('./files/1.txt', 'utf8')
.then((r1) => {
console.log(r1);
return thenFs.readFile('./files/2.txt', 'utf8')
}).then((r2) => {
console.log(r2);
return thenFs.readFile('./files/33.txt', 'utf8')
}).then((r3) => {
console.log(r3);
})
通过链式调用姐简洁的实现了按顺序读取文件1,2,3的内容 。
四、Promise.catch()
通过 .catch 捕获错误
在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype. catch 方法进行捕获和处理:
thenFs.readFile('./files/11.txt', 'utf8')//(文件路径错误,导致后面3个.then()都无法执行)
.then((r1) => {
console.log(r1);
return thenFs.readFile('./files/2.txt', 'utf8')
}).then((r2) => {
console.log(r2);
return thenFs.readFile('./files/33.txt', 'utf8')
}).then((r3) => {
console.log(r3);
}).catch((err) => { // 捕获第一行错误 输出错误内容
console.log(err.message);
})
如果不希望前面的错误导致后续的 .then 无法正常执行,则可以将 .catch 的调用提前,示例代码如下:
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/33.txt', 'utf8')
}).then((r3) => {
console.log(r3);
})
五、Promise.all()和Promise.race() 方法
Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then 操作(等待机制)。
Promise.race() 方法会发起并行的 Promise 异步操作, 只要任何一个异步操作完成,就立即执行下一步的 .then 操作 (赛跑机制)。
示例代码如下:
import thenFs from "then-fs";
const promiseArr = [
thenFs.readFile('./files/1.txt', 'utf8'),
thenFs.readFile('./files/2.txt', 'utf8'),
thenFs.readFile('./files/3.txt', 'utf8')
]
// Promise.all(promiseArr).then((result) => { //所有完成才返回
Promise.race(promiseArr).then((result) => { //有一个完成了就返回
console.log(result);
})