1. 程式人生 > 其它 >手擼一個Promise

手擼一個Promise

技術標籤:JavaScriptjs

/* 
	要做的事情(總結):
    1.promise  是一個類 在執行和這個類的時候需要傳遞一個執行器  執行器會立即執行
    2.promise  有三種狀態  成功(fulfilled)  失敗(rejected)  等待(pending)
    pending==>fulfilled
    pending==>rejected   狀態發生改變不能進行更改
    3. resolve 和 reject 函式是用來更改狀態的
    resolve:成功
    reject:失敗
    4.then 方法內部做的事情就是判斷狀態  狀態成功呼叫成功回撥   如果失敗呼叫失敗回撥 (被定義在原型物件)
    5、then 成功回撥的引數  表示成功之後的值  then失敗回撥中的引數 表示失敗後的原因
 */
const PENDING = "pending"; //等待 const FULFILLED = "fulfilled"; //成功 const REJECTED = "rejected"; //失敗 class MyPromise { constructor(executor) { try { executor(this.resolve, this.reject); } catch (error) { this.reject(error) }
} //狀態 status = PENDING; //預設等待 //成功後的值 value = undefined; //失敗後的原因 reason = undefined; //成功回撥 successCallback = []; //失敗回撥 failCallback = []; resolve = value => { // 如果狀態不是等待 阻止向下執行 if (this.status !== PENDING) return; //狀態成功 this.
status = FULFILLED; // 儲存成功後的值 this.value = value; //判斷成功回撥是否存在 如果存在呼叫 // this.successCallback && this.successCallback(this.value) while (this.successCallback.length) this.successCallback.shift()() } reject = reason => { if (this.status !== PENDING) return; //狀態失敗 this.status = REJECTED; // 儲存失敗後的原因 this.reason = reason; //判斷失敗回撥是否存在 如果存在呼叫 // this.failCallback && this.failCallback(this.reason) while (this.failCallback.length) this.failCallback.shift()() } then(successCallback, failCallback) { successCallback = successCallback ? successCallback : value => value; failCallback = failCallback ? failCallback : reason => { throw reason } let promise1 = new MyPromise((resolve, reject) => { // 判斷狀態 if (this.status === FULFILLED) { //成功 setTimeout(() => { try { let x = successCallback(this.value) //判斷x 是普通值還是promise物件 // 如果是普通值 直接呼叫resolve // 如果是promise物件檢視物件返回結果 // 再根據promise物件返回的結果決定是呼叫resolve還是reject resolvePromise(promise1, x, resolve, reject); } catch (error) { reject(error) } }, 0) } else if (this.status === REJECTED) { //失敗 setTimeout(() => { try { let x = failCallback(this.reason) //判斷x 是普通值還是promise物件 // 如果是普通值 直接呼叫resolve // 如果是promise物件檢視物件返回結果 // 再根據promise物件返回的結果決定是呼叫resolve還是reject resolvePromise(promise1, x, resolve, reject); } catch (error) { reject(error) } }, 0) } else { //等待 //儲存成功回撥 失敗回撥 this.successCallback.push(() => { setTimeout(() => { try { let x = successCallback(this.value) //判斷x 是普通值還是promise物件 // 如果是普通值 直接呼叫resolve // 如果是promise物件檢視物件返回結果 // 再根據promise物件返回的結果決定是呼叫resolve還是reject resolvePromise(promise1, x, resolve, reject); } catch (error) { reject(error) } }, 0) }); this.failCallback.push(() => { setTimeout(() => { try { let x = failCallback(this.reason) //判斷x 是普通值還是promise物件 // 如果是普通值 直接呼叫resolve // 如果是promise物件檢視物件返回結果 // 再根據promise物件返回的結果決定是呼叫resolve還是reject resolvePromise(promise1, x, resolve, reject); } catch (error) { reject(error) } }, 0) }); } }) return promise1; } finally(callback){ return this.then(value=>{ return MyPromise.resolve(callback()).then(()=>value) },reason=>{ return MyPromise.resolve(callback()).then(()=>{throw reason}) }) } catch(failCallback){ return this.then(undefined,failCallback); } static all(array){ let result = []; let index = 0; return new MyPromise((resolve,reject)=>{ function addData(key,value){ result[key] = value; index++; if(index==array.lengt){ resolve(result) } } for(let i = 0;i<array.length;i++){ let current = array[i] if(current instanceof MyPromise){ //promise current.then(value=>addData(i,value),reason=>reject(reason)) }else{ //普通值 addData(i,array[i]) } } }) } static resolve(value){ if(value instanceof MyPromise) return value; return new MyPromise(resolve=>resolve(value)); } } function resolvePromise(promise1, x, resolve, reject) { if (promise1 === x) { return reject(new TypeError("promise不能迴圈呼叫自己")) } if (x instanceof MyPromise) { //是promise物件 // x.then(value=>resolve(value),reason=>reject(reason)) x.then(resolve, reject); } else { //是普通值 resolve(x); } } module.exports = MyPromise;