手写实现 Promise
发布于: 2020 年 07 月 21 日
Promise状态:Pending、Fullfilled、Rejected
Promise 对象的 then 方法会返回一个新的 Promise 对象
后面的 then 方法就是在为上一个 then 返回的 Promise 注册回调
前面 then 方法中回调函数的返回值会作为后面 then 方法回调的参数
如果回调中返回的是 Promise,那后面 then 方法的回调会等待它的结束
源码实现:
// Promise 有三种状态:pending、fulfilled,rejectedconst PENDING = "pending";const FULFILLDED = "fulfilled";const REJECTED = "rejected";// Promise是个类class MyPromise { constructor(executor) { try { executor(this.resolve, this.reject); } catch (error) { this.reject(error); } } // promise初始化状态 status = PENDING; // 成功后的值 value = undefined; // 失败的原因 reason = undefined; // 成功回调 successCallback = []; // 失败回调 failCallback = []; changeStatus(status, value) { // 如果状态不是pending,则直接返回 if (this.status !== PENDING) return; // 将状态变更为成功或者失败 this.status = status; // 保存成功或者失败的值 this.value = value; // 如果状态成功 if (status === FULFILLDED) { while (this.successCallback.length) this.successCallback.shift()(); } else { while (this.failCallback.length) this.failCallback.shift()(); } } resolve = (value) => { this.changeStatus(FULFILLDED, value); }; reject = (reason) => { this.changeStatus(REJECTED, reason); }; then(successCallback, failCallback) { successCallback = successCallback ? successCallback : (value) => value; failCallback = failCallback ? failCallback : (reason) => { throw reason; }; let newPromise = new MyPromise((resolve, reject) => { // 判断状态 if (this.status === FULFILLDED) { // 通过设置setTimeout将下面代码变成异步代码达到避免获取不到newPromise对象问题 setTimeout(() => { try { const x = successCallback(this.value); // 判断 x 的值是普通值还是Promise对象 // 如果是普通值 直接调用resolve // 如果是Promise对象 查看Promise对象返回的结果 // 再根据Promise对象返回的结果 决定调用resolve 还是调用reject promiseThen(newPromise, x, resolve, reject); } catch (error) { reject(error); } }, 0); } else if (this.status === REJECTED) { // 通过设置setTimeout将下面代码变成异步代码达到避免获取不到newPromise对象问题 setTimeout(() => { try { const x = failCallback(this.reason); // 判断 x 的值是普通值还是Promise对象 // 如果是普通值 直接调用resolve // 如果是Promise对象 查看Promise对象返回的结果 // 再根据Promise对象返回的结果 决定调用resolve 还是调用reject promiseThen(newPromise, x, resolve, reject); } catch (error) { reject(error); } }, 0); } else { // 状态为pending // 将成功回调和失败回调都存储起来 this.successCallback.push(() => { setTimeout(() => { try { const x = successCallback(this.value); // 判断 x 的值是普通值还是Promise对象 // 如果是普通值 直接调用resolve // 如果是Promise对象 查看Promise对象返回的结果 // 再根据Promise对象返回的结果 决定调用resolve 还是调用reject promiseThen(newPromise, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); this.failCallback.push(() => { setTimeout(() => { try { const x = failCallback(this.reason); // 判断 x 的值是普通值还是Promise对象 // 如果是普通值 直接调用resolve // 如果是Promise对象 查看Promise对象返回的结果 // 再根据Promise对象返回的结果 决定调用resolve 还是调用reject promiseThen(newPromise, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } }); // 返回Promise对象 return newPromise; } finally(callback) { return this.then((value) => { return MyPromise.resolve(callback()).then(() => value); }); } // catch(callback) { return this.then(undefined, callback); } static all(array) { return new MyPromise((resolve, reject) => { let result = []; let count = 0; function addData(index, value) { result[key] = value; count++; if (count === array.length) { resolve(result); } } array.forEach((item, index) => { if (item instanceof MyPromise) { // Promise对象 item.then( (value) => addData(index, value), (reason) => reject(reason) ); } else { // 普通值 addData(index, item); } }); }); } static resolve(value) { if (value instanceof MyPromise) return value; return new MyPromise((resolve) => resolve(value)); } static reject(reason) { if (reason instanceof MyPromise) return reason; return new MyPromise((_, reject) => reject(reason)); }}function promiseThen(promise, x, resolve, reject) { if (promise === x) { // 拒绝自我调用 reject(new TypeError("Chaining cycle detected for promise #<Promise>")); } if (x instanceof MyPromise) { x.then( (value) => resolve(value), (reason) => reject(reason) ); } else { // 普通值 resolve(x); }}module.exports = MyPromise;
划线
评论
复制
发布于: 2020 年 07 月 21 日阅读数: 56
GKNick
关注
还未添加个人签名 2018.12.12 加入
还未添加个人简介
评论