源碼地址git
先看基本使用github
const promise = new Promise((resolve, reject) => { resolve(value) // or reject(reason) })
建立Promise時傳入的回調函數是當即執行的,因此咱們的Promise應該是這樣(用ts實現)typescript
function BDuckPromise(fn: (resolve: (value: any) => void, reject: (reason: any) => void) => any) { function resolve(value: any) { } function reject(reason: any) { } fn(resolve, reject); }
每一個Promise對象都有三種生命狀態:PENDING(未開始)、FULFILLED(已完成)、REJECTED(已失敗)。生命狀態只能是PENDING => FULFILLED 或者 PENDING => REJECTED 且一旦發生改變不可逆轉。此時咱們的代碼是這樣,具備了狀態。promise
enum STATE { PENDING = 0, FULFILLED = 1, REJECTED = 2 } function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) { let store = null, state = STATE.PENDING function resolve(value: any): void { store = value; state = STATE.FULFILLED; } function reject(reason: any): void { store = reason; state = STATE.REJECTED; } fn(resolve, reject) }
一個Promise對象回調中傳入的值(value)或者拒因(reason)是在該示例對象的then函數中獲取的函數
promise.then(value => { console.log(value); return value + 1 }, reason => { // .... })
then具備兩個回調函數onfulfilled(用於成功時傳遞value)、onrejected(用於失敗時傳遞reason)this
因此咱們then方法大概是長這樣子code
function BDuckPromise() { this.then = (onfulfilled, onrejected) => { if(state === STATE.PENDING) { return } if(state === STATE.FULFILLED) { onfulfilled(store) return } if(state === STATE.REJECTED) { onrejected(store) return } } }
可是等一下,若是咱們寫成這個樣子當咱們調用then的時候就必需要求promise的狀態已經發生過改變咱們才能獲取到value或者reason,這個顯然不是咱們須要的。可是咱們應該要寫成什麼樣呢?分析一下對象
當咱們調用then時候promise仍然處於pending狀態時,咱們應該怎麼將value或者reason在它狀態發生改變是傳遞出去呢?ip
顯然,咱們應該在狀態發生改變時調用對應的onfulfilled或者onrejected回調。jsx
那麼咱們就應該在狀態爲pending時將回調函數都存儲起來,一旦狀態改變了,就調用這些回調函數,這下就清楚了,應當在resolve或者reject中調用咱們的onfulfilled或者onrejected回調
enum STATE { PENDING = 0, FULFILLED = 1, REJECTED = 2 } function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) { let store = null, state = STATE.PENDING, callbacks = []; function resolve(value: any): void { store = value; state = STATE.FULFILLED; callbacks.forEach(callback => { if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) { callback.onfulfilled(store) } }); callbacks = null }; function reject(reason: any): void { store = reason; state = STATE.REJECTED; callbacks.forEach(callback => { if(callback.onrejected && 'function' === typeof callback.onrejected) { callback.onrejected(store) } }); callbacks = null }; this.then = (onfulfilled, onrejected) => { if(state === STATE.PENDING) { callbacks.push({ onfulfilled, onrejected }) return } if(state === STATE.FULFILLED) { onfulfilled(store) return } if(state === STATE.REJECTED) { onrejected(store) return } }; fn(resolve, reject) }
then函數是有返回值的,且返回的的是一個新的Promise對象,因此還得改=_=!
const promise1 = new Promise((resolve, reject) => { resolve(1) }) // promise2 是一個新的Promise對象 const promise2 = promise1.then(value => { return value + 1 })
如今改爲這樣子
this.then = (onfulfilled, onrejected) => { return new BDuckPromise((_resolve, _reject) => { if(state === STATE.PENDING) { callbacks.push({ onfulfilled, onrejected }) return } if(state === STATE.FULFILLED) { onfulfilled(store) return } if(state === STATE.REJECTED) { onrejected(store) return } }); }
上一個then函數中return的值會傳遞給下一個then中做爲值
const promise1 = new Promise((resolve, reject) => { resolve(1) }) // promise2 是一個新的Promise對象 const promise2 = promise1.then(value => { return value + 1 }) .then(value => { console.log(value) // 2 })
好吧,接着改=_=
this.then = (onfulfilled, onrejected) => { return new BDuckPromise((_resolve, _reject) => { if(state === STATE.PENDING) { callbacks.push({ onfulfilled, onrejected, _resolve, _reject }) return } if(state === STATE.FULFILLED) { const ret = onfulfilled(store) _resolve(ret) return } if(state === STATE.REJECTED) { const ret = onrejected(store) _reject(ret) return } }); } // 相應的resolve, reject也作相應的更改 function resolve(value: any): void { store = value; state = STATE.FULFILLED; callbacks.forEach(callback => { if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) { const ret = callback.onfulfilled(store) callback._resolve(ret) } }) } function reject(reason: any): void { store = reason; state = STATE.REJECTED; callbacks.forEach(callback => { if(callback.onrejected && 'function' === typeof callback.onrejected) { const ret = callback.onrejected(store) callback._reject(ret) } }) }
若是then中return的是一個新的Promise則下一個then中的value或reason是這個返回的Promise中resolve或者reject中傳遞value或者reason
enum STATE { PENDING = 0, FULFILLED = 1, REJECTED = 2 } function BDuckPromise(fn: (resolve:(value: any) => void, reject: (reason: any) => void) => any) { let store:any = null, state = STATE.PENDING, callbacks:any = [] function resolve(value: any): void { setTimeout(() => { state = STATE.FULFILLED; // value 是一個Promise對象 if(value && 'object' === typeof value && value.then && 'function' === typeof value.then) { // do then value.then(resolve, reject) return } // value 不是Promise對象 store = value; callbacks.forEach(callback => { if(callback.onfulfilled && 'function' === typeof callback.onfulfilled) { const ret = callback.onfulfilled(store) callback._resolve(ret) } }) callbacks = [] }) } function reject(reason: any): void { setTimeout(() => { state = STATE.REJECTED; // value 是一個Promise對象 if(reason && 'object' === typeof reason && reason.then && 'function' === typeof reason.then) { reason.then(resolve, reject) return } // value 不是Promise對象 store = reason; callbacks.forEach(callback => { if(callback.onrejected && 'function' === typeof callback.onrejected) { const ret = callback.onrejected(store) callback._reject(ret) } }) callbacks = [] }, 0) } this.then = (onfulfilled, onrejected) => { return new BDuckPromise((_resolve, _reject) => { if(state === STATE.PENDING) { callbacks.push({ onfulfilled, onrejected, _resolve, _reject }) return } if(state === STATE.FULFILLED) { const ret = onfulfilled(store) _resolve(ret) return } if(state === STATE.REJECTED) { const ret = onrejected(store) _reject(ret) return } }); } fn(resolve, reject) } export default BDuckPromise;