class Promise { static resolve() {} static reject() {} static PENDING = "pending"; static RESOLVED = "resolved"; static REJECTED = "rejected"; constructor(exector) { this.state = Promise.PENDING; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { if (this.state === Promise.PENDING) { this.value = value; this.state = Promise.RESOLVED; this.onResolvedCallbacks.forEach((fn) => fn(this.value)); } }; const reject = (reason) => { if (this.state === Promise.PENDING) { this.reason = reason; this.state = Promise.REJECTED; this.onRejectedCallbacks.forEach((fn) => fn(this.reason)); } }; try { exector(resolve, reject); } catch (e) { reject(e); } } then(onFulFilled, onRejected) { onFulFilled = typeof onFulFilled === "function" ? onFulFilled : (value) => value; onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason; }; let promise = new Promise((resolve, reject) => { if (this.state === Promise.PENDING) { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }, 0); }); } if (this.state === Promise.RESOLVED) { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }, 0); } if (this.state === Promise.REJECTED) { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch (error) { reject(error); } }, 0); } }); return promise; } catch() {}}function resolvePromise(promise, x, resolve, reject) { if (x === promise) { reject( new TypeError("TypeError: Chaining cycle detected for promise #") ); } let called = false; if ((typeof x === "object" && x !== null) || typeof x === "function") { try { let then = x.then; if (typeof then === "function") { then.call( x, (y) => { if (called) return; called = true; resolvePromise(promise, y, resolve, reject); }, (r) => { if (called) return; called = true; reject(r); } ); } else { if (called) return; called = true; resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); }}Promise.deferred = function () { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }); return dfd;};module.exports = Promise;
Original: https://blog.51cto.com/hefeng6500/5394170
Author: 兰亭古墨
Title: 手写 promise
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/517260/
转载文章受原作者版权保护。转载请注明原作者出处!