简易版
class Promise {success = []failure = []constructor(fn) {const resolve = (data) => {setTimeout(() => {for (let i = 0; i < this.success.length; i++) {this.success[i](data)}})}const reject = (reason) => {setTimeout(() => {for (let i = 0; i < this.failure.length; i++) {this.failure[i](reason)}})}fn(resolve, reject)}then(s, f) {this.success.push(s)this.failure.push(f)return this}}
完整版
// 三种状态const PENDING = "pending";const RESOLVED = "resolved";const REJECTED = "rejected";// promise 接收一个函数参数,该函数会立即执行function MyPromise(fn) {let _this = this;_this.currentState = PENDING;_this.value = undefined;// 用于保存 then 中的回调,只有当 promise// 状态为 pending 时才会缓存,并且每个实例至多缓存一个_this.resolvedCallbacks = [];_this.rejectedCallbacks = [];_this.resolve = function (value) {if (value instanceof MyPromise) {// 如果 value 是个 Promise,递归执行return value.then(_this.resolve, _this.reject)}setTimeout(() => { // 异步执行,保证执行顺序if (_this.currentState === PENDING) {_this.currentState = RESOLVED;_this.value = value;_this.resolvedCallbacks.forEach(cb => cb());}})};_this.reject = function (reason) {setTimeout(() => { // 异步执行,保证执行顺序if (_this.currentState === PENDING) {_this.currentState = REJECTED;_this.value = reason;_this.rejectedCallbacks.forEach(cb => cb());}})}// 用于解决以下问题// new Promise(() => throw Error('error))try {fn(_this.resolve, _this.reject);} catch (e) {_this.reject(e);}}MyPromise.prototype.then = function (onResolved, onRejected) {var self = this;// 规范 2.2.7,then 必须返回一个新的 promisevar promise2;// 规范 2.2.onResolved 和 onRejected 都为可选参数// 如果类型不是函数需要忽略,同时也实现了透传// Promise.resolve(4).then().then((value) => console.log(value))onResolved = typeof onResolved === 'function' ? onResolved : v => v;onRejected = typeof onRejected === 'function' ? onRejected : r => throw r;if (self.currentState === RESOLVED) {return (promise2 = new MyPromise(function (resolve, reject) {// 规范 2.2.4,保证 onFulfilled,onRjected 异步执行// 所以用了 setTimeout 包裹下setTimeout(function () {try {var x = onResolved(self.value);resolutionProcedure(promise2, x, resolve, reject);} catch (reason) {reject(reason);}});}));}if (self.currentState === REJECTED) {return (promise2 = new MyPromise(function (resolve, reject) {setTimeout(function () {// 异步执行onRejectedtry {var x = onRejected(self.value);resolutionProcedure(promise2, x, resolve, reject);} catch (reason) {reject(reason);}});}));}if (self.currentState === PENDING) {return (promise2 = new MyPromise(function (resolve, reject) {self.resolvedCallbacks.push(function () {// 考虑到可能会有报错,所以使用 try/catch 包裹try {var x = onResolved(self.value);resolutionProcedure(promise2, x, resolve, reject);} catch (r) {reject(r);}});self.rejectedCallbacks.push(function () {try {var x = onRejected(self.value);resolutionProcedure(promise2, x, resolve, reject);} catch (r) {reject(r);}});}));}};// 规范 2.3function resolutionProcedure(promise2, x, resolve, reject) {// 规范 2.3.1,x 不能和 promise2 相同,避免循环引用if (promise2 === x) {return reject(new TypeError("Error"));}// 规范 2.3.2// 如果 x 为 Promise,状态为 pending 需要继续等待否则执行if (x instanceof MyPromise) {if (x.currentState === PENDING) {x.then(function (value) {// 再次调用该函数是为了确认 x resolve 的// 参数是什么类型,如果是基本类型就再次 resolve// 把值传给下个 thenresolutionProcedure(promise2, value, resolve, reject);}, reject);} else {x.then(resolve, reject);}return;}// 规范 2.3.3.3.3// reject 或者 resolve 其中一个执行过得话,忽略其他的let called = false;// 规范 2.3.3,判断 x 是否为对象或者函数if (x !== null && (typeof x === "object" || typeof x === "function")) {// 规范 2.3.3.2,如果不能取出 then,就 rejecttry {// 规范 2.3.3.1let then = x.then;// 如果 then 是函数,调用 x.thenif (typeof then === "function") {// 规范 2.3.3.3then.call(x,y => {if (called) return;called = true;// 规范 2.3.3.3.1resolutionProcedure(promise2, y, resolve, reject);},e => {if (called) return;called = true;reject(e);});} else {// 规范 2.3.3.4resolve(x);}} catch (e) {if (called) return;called = true;reject(e);}} else {// 规范 2.3.4,x 为基本类型resolve(x);}}
