1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| const PENDING = "pending"; const FULFILLED = "fulfilled"; const REJECTED = "rejected";
function runMicrotasks(callback) { if (process && process.nextTick) { process.nextTick(callback); } else if (MutationObserver) { const p = document.createElement("p"); const observer = new MutationObserver(callback); observer.observe(p, { childList: true }); p.innerHTML = 1; } else { setTimeout(callback, 0); } }
function isPromise(obj) { return ( !!obj && (typeof obj === "object" || typeof obj === "function") && typeof obj.then === "function" ); }
class MyPromise {
constructor(executor) { this._state = PENDING; this._value = undefined; this._handlers = []; try { executor(this._resolve.bind(this), this._reject.bind(this)); } catch (error) { this._reject(error); } } _changeState(newState, value) { if (this._state !== PENDING) { return; } this._state = newState; this._value = value; this._runHandlers(); } _pushHandler(executor, state, resolve, reject) { this._handlers.push({ executor, state, resolve, reject, }); } _runOneHandler(handler) { runMicrotasks(() => { if (this._state !== state) { return; } if (typeof executor !== "function") { this._state === FULFILLED ? resolve(this._value) : reject(this._value); return; } try { if (isPromise(result)) { result.then(resolve, reject); } else { resolve(result); } } catch (error) { reject(error); } }); } _runHandlers() { if (this._state === PENDING) { return; } while (this._handlers[0]) { const handler = this._handlers[0]; this._runOneHandler(handler); this._handlers.shift(); } } then(onFulfilled, onRejected) { return new myPromise((resolve, reject) => { this._pushHandler(onFulfilled, FULFILLED, resolve, reject); this._pushHandler(onRejected, REJECT, resolve, reject); this._runHandlers(); }); }
_resolve(data) { this._changeState(FULFILLED, data); } _reject(reason) { this._changeState(REJECTED, reason); } } const pro = new Promise((resolve, reject) => { resolve(1); }); console.log(pro);
|