关于Promise
一、Promise 使用
Promise 是一个构造函数,接收一个 excutor 函数,该函数接收两个函数类型的参数,一般约定叫 resolve 和 reject。调用 new Promise 返回一个实例对象。
const promise = new Promise((resolve, reject) => { // 异步处理 // 处理结束后,调用 resolve 或 reject })
1.1 Promise 实例对象方法
1.1.1 then 方法
promise.then(onResolved, onRejected)
then 方法接收两个函数参数,当 Promise 构造函数中执行了 resolve() , 此处 onResolved 函数便会执行;当 Promise 构造函数中执行了 reject(),此处 onRejected 函数便会执行。需要说明的是,调用 then 方法会返回一个新的 promise 实例对象,所以可以链式调用。
const promise = new Promise((resolve, reject) => { const code = 200 || 404 if (code === 200) { resolve('success') } else if (code === 404) { reject('fail') } }) promise.then(result => { console.log(result) }, reason => { console.log(reason) })
1.1.2 catch 方法
如果只想对异常进行处理时可以采用 promise.then(undefined, onRejected)
这种方式,只指定 reject 时的回调函数。 不过这种情况下最好用 promise.catch(onRejected)
。
在调用链中捕获错误
function taskA() { console.log("任务一 执行") throw new Error('执行任务一时发生未知异常') } function taskB() { console.log("任务二 执行") return Promise.reject('执行任务二时发生已知错误') } function catchError(error) { console.log("捕获错误", error) } function finalTask() { console.log("最终任务") } var promise = Promise.resolve(); promise .then(taskA) .catch(catchError) .then(taskB) .catch(catchError) .then(finalTask)
在 taskA 或 taskB 的处理中,如果【发生异常】或【返回了一个 Rejected 状态的 promise 对象】就会调用 onRejected 方法。
1.1.3 finally 方法
1.2 Promise 静态方法
1.2.1 Promise.resolve
返回一个 fulfilled 状态的 promise 对象
const promise = Promise.resolve('success') // 相当于 const promise = new Promise((resolve, reject) => { resolve('success') })
1.2.2 Promise.reject
返回一个 rejected 状态的 promise 对象
const promise = Promise.reject('fail') // 相当于 const promise = new Promise((resolve, reject) => { reject('fail') })
1.2.3 Promise.all
接收一个数组参数,数组元素需都是 promise 实例对象。通常用于并发执行多个异步操作,只有全部实例执行了 resolve 完之后才会执行 then 中第一个回调函数,得到一个数组类型的结果。假如其中一个执行了 reject,则立即执行 then 中第二个回调函数。
const p1 = new Promise((resolve, reject) => { resolve(1); }); const p2 = new Promise((resolve, reject) => { resolve(2); }); const p3 = new Promise((resolve, reject) => { resolve(3); }); Promise.all([p1, p2, p3]).then(data => { console.log(data); // [1, 2, 3] 结果顺序和 promise 实例数组顺序是一致的 }, err => { console.log(err) })
1.2.4 Promise.race
接收一个数组参数,数组元素需都是 promise 实例对象。只要有一个实例进入 FulFilled 或者 Rejected 状态的话,就会继续进行后面的处理。
function promisedTimer(delay) { return new Promise(function (resolve, reject) { setTimeout(function () { resolve(delay) }, delay) }); } var startDate = Date.now(); Promise.race([ promisedTimer(10), promisedTimer(20), promisedTimer(30) ]).then(function (values) { console.log(values) // 10 })
1.2.5 Promise.allSettled
1.2.6 Promise.any
1.2.7 Promise.try
二、Promise 实现
先看下Promise的基础功能
const promise = new Promise((resolve, reject) => { resolve('success') reject('err') }) promise.then(value => { console.log('resolve', value) }, reason => { console.log('reject', reason) }) // 输出 resolve success
Promise基本原理
1、Promise是一个类,实例化这个类的时候会传入一个执行器,这个执行器会立即执行,相当于同步代码。
2、Promise会有三种状态:
- Pending 等待
- Fulfilled 完成
- Rejected 失败
3、状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,一旦发生改变便不可二次修改。
4、使用 resolve 和 reject 两个函数来更改状态。
5、then 方法内部做的事情就是状态判断:
- 如果状态是成功,调用成功回调函数
- 如果状态是失败,调用失败回调函数
三、一些考察题目
new Promise((resolve, reject) => { console.log("外部promise"); resolve(); }) .then(() => { console.log("外部第一个then"); return new Promise((resolve, reject) => { console.log("内部promise"); resolve(); }) .then(() => { console.log("内部第一个then"); }) .then(() => { console.log("内部第二个then"); }); }) .then(() => { console.log("外部第二个then"); }); // 依次输出:外部promise、外部第一个then、内部promise、内部第一个then、内部第二个then、外部第二个then
题目2
// 把题目1中的 return 去掉,结果就不同了。 // 输出会变成:外部promise、外部第一个then、内部promise、内部第一个then、外部第二个then、内部第二个then 。
题目3
Promise.resolve().then(() => { console.log(0); return Promise.resolve(4); }).then((res) => { console.log(res) }) Promise.resolve().then(() => { console.log(1); }).then(() => { console.log(2); }).then(() => { console.log(3); }).then(() => { console.log(5); }).then(() =>{ console.log(6); }) // 输出 0123456 // 出自:https://mp.weixin.qq.com/s/lRFlFZ62_ndiuF7qO8ofZg