/** * promise 的 三种状态 */const PENDING = "PENDING", FULFILLED = "FULFILLED", REJECED = "REJECTED";/** * * @param {*} p2 p2 就是promise * @param {*} x onFulfilled 或者 onRejected的返回值 * @param {*} resolve * @param {*} reject * @returns */function resolvePromise(p2, x, resolve, reject) { // console.log(p2===x); if (p2 === x) { // 解决循环引用 return reject(new TypeError(" Chaining cycle detected for promise #<MyPromiseFinal>")) } // called 是否已经调用过resolve 或者是reject let called = false; // 2.3.3 if ((typeof x === "object" && x !== null) || typeof x === "function") { try { // 获取then的时候可能被劫持 Object.defineProperty 中被劫持 let then = x.then; if (typeof then === "function") { // Promise 可以断定 then.call(x, (y) => { if (called) return; called = true; // y可能是 MyPromise对象 resolvePromise(p2, y, resolve, reject); // resolve(y); }, (r) => { if (called) return; called = true; reject(r); }) } else { resolve(x); } } catch (error) { if (called) return; called = true; reject(error); } } else { resolve(x); }}/** * * @param {*} x 判断x是否是promise * @returns */function isPromise(x){ if((typeof x === "object" && x !== null) || typeof x === "function"){ try { let then = x.then; if(typeof then === "function"){ return true; }else{ return false; } } catch (error) { return false; } } return false;}/** * * @param {data} data * @returns 判断数据是否是可迭代对象 */function isIterable(data){ return data !== null && data !== undefined && typeof data[Symbol.iterator] === 'function'}class MyPromiseFinal { constructor(fn) { // 初始化状态 this.status = PENDING; // 成功值 this.value = undefined; // 失败的元婴赋值为 this.reason = undefined; // 成功态的回调函数集合 this.onFulFilledCallbacks = []; // 失败态的回调函数集合 this.onRejectedCallbacks = []; // 将promise 从 pending -> resolve的状态 let resolve = (value) => { // 判断是否是thenable对象 if(value instanceof MyPromiseFinal){ // 如果value 还是 MyPromiseFinal的实例 那么久执行then // 如果还是MyPromiseFinal 那么继续走resolve 直到不是promise为止 return value.then(resolve,reject); } if (this.status === PENDING) { this.status = FULFILLED; this.value = value; // 发布 this.onFulFilledCallbacks.forEach(fn => fn()); } } // 将promise 从 pending -> rejected的状态 赋值原因 let reject = (reason) => { if (this.status === PENDING) { this.status = REJECED; this.reason = reason; // 发布 this.onRejectedCallbacks.forEach(fn => fn()); } } // executor fn(resolve, reject); } // x 可能是 1 字符串1 bool 类型 但是可能是 Promise then(onFulFilled, onRejected) { // then 穿透 onFulfilled onRejected 是可选参数 onFulFilled = typeof onFulFilled === "function" ? onFulFilled : value => value; //直接返回成功态的值 onRejected = typeof onRejected === "function" ? onRejected : reason => { throw (reason) }; // then 必须返回一个promise对象 let promise2 = new MyPromiseFinal((resolve, reject) => { if (this.status === FULFILLED) { // 为什么使用 setTimeout 参考promiseA+ 3.1 setTimeout(() => { // if (called) return; // called = true; try { let x = onFulFilled(this.value);// 可能onFulFilled 抛出错误 resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }, 0); } if (this.status === REJECED) { setTimeout(() => { // if (called) return; // called = true; try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }, 0); } if (this.status === PENDING) { this.onFulFilledCallbacks.push(() => { setTimeout(() => { try { let x = onFulFilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }, 0); }) this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (error) { reject(error) } }, 0); }) } }); return promise2 } catch(reject) { return this.then(null, reject) } /** * Promise.reoslve("common value").finally(()=>{ * console.log(1); * return new Promise((resolve,reject)=>{ * reject(123); * }) * }).then(data=>{ * console.log(data); * }).catch(err=>console.log(err)) */ finally(finallyCallback){ return this.then((value)=>{ return MyPromiseFinal.resolve(finallyCallback()).then(()=>{ return value }) },(reason)=>{ return MyPromiseFinal.resolve(finallyCallback()).then(()=>{ throw reason }) }) } static resolve(value){ return new MyPromiseFinal((resolve,reject)=>{ resolve(value); }) } static reject(reason){ return new MyPromiseFinal((resolve,reject)=>{ reject(reason); }) } static all(promiseArr){ let id = 0, resArr =[]; function formatPromise(value,idx,resolve){ resArr[idx] = value; if(++id === promiseArr.length){ resolve(resArr); } } return new MyPromiseFinal((resolve,reject)=>{ promiseArr.forEach((promise,idx)=>{ if(isPromise(promise)){ promise.then((value)=>{ formatPromise(value,idx,resolve); },reject) }else{ formatPromise(promise,idx,resolve); } }) }) } static race(promiseArr){ let res; function formatRacePromise (x,resolve,reject){ if(res)return; res = x; if(resolve){ resolve(x); }else{ reject(x); } } return new MyPromiseFinal((resolve,reject)=>{ promiseArr.map((promise,idx)=>{ if(isPromise(promise)){ promise.then((res)=>{ formatRacePromise(res,resolve,reject); },(reason) =>{ formatRacePromise(reason,null,reject); // reject(reason) }) }else{ resolve(promise); } }) }) } static race2(promiseArr){ return new MyPromiseFinal((resolve,reject)=>{ promiseArr.map((promise,idx) => { if(isPromise(promise)){ promise.then(resolve,reject); } }) }) } static allSettled(promiseArr){ let resArr = [], idx = 0; function handlePromiseRes(status,value,resolve){ switch(status){ case "fulfilled": resArr.push({ status, value }); break; case "rejected": resArr.push({ status, reason:value }) } if(++idx === promiseArr.length){ resolve(resArr); } } return new MyPromiseFinal((resolve,reject)=>{ if(!isIterable(promiseArr)){ throw new TypeError(promiseArr +" is not iterable (cannot read property Symbol(Symbol.iterator))") } if(promiseArr.length===0){ resolve(resArr); } promiseArr.map((promise,idx)=>{ if(isPromise(promise)){ promise.then((value)=>{ handlePromiseRes("fulfilled",value, resolve); },(reason) =>{ handlePromiseRes("rejected",reason, resolve); }) }else{ handlePromiseRes("fulfilled",promise, resolve); } }) }) }}// 检测Promise 是否符合promiseA+规范 MyPromiseFinal.defer = MyPromiseFinal.deferred = function () { let deferred = {}; deferred.promise = new MyPromiseFinal((resolve, reject) => { deferred.resolve = resolve; deferred.reject = reject; }) return deferred;}module.exports = MyPromiseFinal;// 循环 引用的例子/* let cycleP = new Promise((resolve,reject)=>{ resolve("123")})let cycleP2 = cycleP.then(data=>{ return cycleP2}) */