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 是一个类,在执行这个类的时候会传入一个执行器,这个执行器会立即执行
Promise 会有三种状态
Pending 等待
Fulfilled 完成
Rejected 失败
状态只能由 Pending --> Fulfilled 或者 Pending --> Rejected,且一但发生改变便不可二次修改;
Promise 中使用 resolve 和 reject 两个函数来更改状态;
then 方法内部做但事情就是状态判断
如果状态是成功,调用成功回调函数
如果状态是失败,调用失败回调函数
下面开始实现:
1. 新建 MyPromise 类,传入执行器 executor
// 新建 MyPromise.js // 新建 MyPromise 类 class MyPromise { constructor(executor){ // executor 是一个执行器,进入会立即执行 executor() } }复制代码
2. executor 传入 resolve 和 reject 方法
// MyPromise.js // 新建 MyPromise 类 class MyPromise { constructor(executor){ // executor 是一个执行器,进入会立即执行 // 并传入resolve和reject方法 executor(this.resolve, this.reject) } // resolve和reject为什么要用箭头函数? // 如果直接调用的话,普通函数this指向的是window或者undefined // 用箭头函数就可以让this指向当前实例对象 // 更改成功后的状态 resolve = () => {} // 更改失败后的状态 reject = () => {} }复制代码
3. 状态与结果的管理
// MyPromise.js // 先定义三个常量表示状态 const PENDING = 'pending'; const FULFILLED = 'fulfilled'; const REJECTED = 'rejected'; // 新建 MyPromise 类 class MyPromise { constructor(executor){ // executor 是一个执行器,进入会立即执行 // 并传入resolve和reject方法 executor(this.resolve, this.reject) } // 储存状态的变量,初始值是 pending status = PENDING; // resolve和reject为什么要用箭头函数? // 如果直接调用的话,普通函数this指向的是window或者undefined // 用箭头函数就可以让this指向当前实例对象 // 成功之后的值 value = null; // 失败之后的原因 reason = null; // 更改成功后的状态 resolve = (value) => { // 只有状态是等待,才执行状态修改 if (this.status === PENDING) { // 状态修改为成功 this.status = FULFILLED; // 保存成功之后的值 this.value = value; } } // 更改失败后的状态 reject = (reason) => { // 只有状态是等待,才执行状态修改 if (this.status === PENDING) { // 状态成功为失败 this.status = REJECTED; // 保存失败后的原因 this.reason = reason; } } }复制代码
4. then 的简单实现
// MyPromise.js then(onFulfilled, onRejected) { // 判断状态 if (this.status === FULFILLED) { // 调用成功回调,并且把值返回 onFulfilled(this.value); } else if (this.status === REJECTED) { // 调用失败回调,并且把原因返回 onRejected(this.reason); } }复制代码
5. 使用 module.exports 对外暴露 MyPromise 类
// MyPromise.js module.exports = MyPromise;复制代码
是不是很简单,其实promise真的没啥难的, 但是特别的实用, 你如果理解这篇文章, 你的功力就大涨了
作者:wh1e3
链接:https://juejin.cn/post/7032550156264603656