const ENUM = { PENDING: 'PENDING', FULFILLED: 'FULFILLED', REJECTED: 'REJECTED' } // 須要兼容其餘人的promise const resolvePromise = (x, promise2, resolve, reject) => { if (x === promise2) { reject(new TypeError(`TypeError: Chaining cycle detected for promise #<Promise>`)) } if ((typeof x === 'object' && x !== null) || typeof x === 'function') { let called; try { let then = x.then; if (typeof then == 'function') { then.call(x, y => { if (called) return; called = true; resolvePromise(y, promise2, resolve, reject); }, r => { if (called) return; called = true; reject(r); }) } else { resolve(x); // {a:1} } } catch (e) { if (called) return; called = true; reject(e); } } else { resolve(x); } } class Promise { constructor(executor) { this.status = ENUM.PENDING; this.value = undefined; // 實例上的屬性 每次new 都會建立一個新的 this.reason = undefined; // 須要建立成功的隊列 失敗的隊列,分別存放 this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; const resolve = (value) => { // 若是value 是一個promise,那咱們的庫中應該也要實現一個遞歸解析 if(value instanceof Promise){ // 遞歸解析 return value.then(resolve,reject) } if (this.status === ENUM.PENDING) { this.status = ENUM.FULFILLED; this.value = value; // 先賦予的值 再循環 this.onResolvedCallbacks.forEach(fn => fn()) } } const reject = (reason) => { if (this.status === ENUM.PENDING) { this.status = ENUM.REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()) } } try { executor(resolve, reject); } catch (e) { reject(e) } } then(onFulfilled, onRejected) { onFulfilled = typeof onFulfilled == 'function' ? onFulfilled : v => v; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }; // 調用then 方法 建立一個新的promise let promise2 = new Promise((resolve, reject) => { // 我須要根據 x 的情況來判斷是調用resolve仍是reject if (this.status == ENUM.FULFILLED) { // todo... setTimeout(() => { try { let x = onFulfilled(this.value); // 解析promise resolvePromise(x, promise2, resolve, reject) } catch (e) { reject(e); } }, 0); } if (this.status == ENUM.REJECTED) { // todo... setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(x, promise2, resolve, reject) } catch (e) { reject(e); } }, 0); } if (this.status == ENUM.PENDING) { // 用戶尚未調用resolve或者reject方法 this.onResolvedCallbacks.push(() => { // todo... setTimeout(() => { try { let x = onFulfilled(this.value); resolvePromise(x, promise2, resolve, reject) } catch (e) { reject(e); } }, 0); }); this.onRejectedCallbacks.push(() => { // todo... setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(x, promise2, resolve, reject) } catch (e) { reject(e); } }, 0); }) } }); return promise2; } catch(errCallback){ return this.then(null,errCallback) } static resolve(val){ return new Promise((resolve,reject)=>{ resolve(val); }) } static reject(reason){ return new Promise((resolve,reject)=>{ reject(reason); }) } } // 產生延遲對象 Promise.prototype.finally = function(callback) { return this.then((value) => { return Promise.resolve(callback()).then(() => value) }, (err) => { return Promise.resolve(callback()).then(() => { throw err }) }); } Promise.all = function(values) { return new Promise((resolve, reject) => { let resultArr = []; let orderIndex = 0; const processResultByKey = (value, index) => { resultArr[index] = value; if (++orderIndex === values.length) { resolve(resultArr) } } for (let i = 0; i < values.length; i++) { let value = values[i]; if (value && typeof value.then === 'function') { value.then((value) => { processResultByKey(value, i); }, reject); } else { processResultByKey(value, i); } } }); } Promise.race = function(promises) { return new Promise((resolve, reject) => { // 一塊兒執行就是for循環 for (let i = 0; i < promises.length; i++) { let val = promises[i]; if (val && typeof val.then === 'function') { val.then(resolve, reject); // value.then(resolve,reject) } else { // 普通值 resolve(val) } } }); }