模擬Promise的功能, 按照下面的步驟,一步一步
1. 新建是個建構函式
2. 傳入一個可執行函式 函式的入參第一個為 fullFill函式 第二個為 reject函式; 函式立即執行, 引數函式非同步執行
3. 狀態一旦更改就不可以變更 只能 pending => fulfilled 或者 pending => rejected
4. then 的時候要處理入參的情況 successCallback 和failCallback 均可能為非函式
- 預設的 failCallback 一定要將異常丟擲, 這樣下一個promise便可將其捕獲 異常冒泡的目的
5. then 中執行回撥的時候要捕獲異常 將其傳給下一個promise
- 如果promise狀態未變更 則將回撥方法新增到對應佇列中
- 如果promise狀態已經變更 需要非同步處理成功或者失敗回撥
- 因為可能出現 回撥結果和當前then返回的Promise一致 從而導致死迴圈問題
6. catch只是then的一種特殊的寫法 方便理解和使用
7. finally 特點
- 不過resolve或者reject都會執行
- 回撥沒有引數
- 返回一個Promise 且值可以穿透到下一個then或者catch
8. Promise.resolve, Promise.reject 根據其引數返回對應的值 或者狀態的Promise即可
9. Proise.all 特點
- 返回一個Promise
- 入參是陣列 resolve的情況下出參也是陣列 且結果順序和呼叫順序一致
- 所有的值或者promise都完成才能resolve 所有要計數
- 只要有一個為reject 返回的Promise便reject
10. Proise.race 特點
- 返回一個Promise
- 入參是陣列 那麼出參根據第一個成功或者失敗的引數來確定
- 只要有一個resolve 或者reject 便更改返回Promise的狀態
const PENDING = 'pending' //等待 const FULFILLED = 'fulfilled' //成功 const REJECTED = 'rejected' //失敗 const fulfilledCallback = [] //成功回撥函式 const rejectedCallback = [] //失敗回撥函式 class MyPromise { constructor (executor) { try{ executor(this.resolve, this.reject) } catch (e){ this.reject(e) } } status = PENDING//promise的狀態 value = undefined//成功之後的值 reason = undefined//失敗之後的值 fulfilledCallback = [] //成功回撥函式 rejectedCallback = [] //失敗回撥函式 resolve = value => { //如果狀態不是等待, 阻止程式繼續往下執行 if(this.status !== PENDING){ return } this.status = FULFILLED this.value = value //判斷成功回撥是否存在,如果存在, 呼叫 // this.fulfilledCallback && this.fulfilledCallback(this.value) while(this.fulfilledCallback.length) this.fulfilledCallback.shift()() } reject = reason => { //如果狀態不是等待, 阻止程式繼續往下執行 if(this.status !== PENDING){ return } this.status = REJECTED this.reason = reason //判斷失敗回撥是否存在,如果存在, 呼叫 // this.rejectedCallback && this.rejectedCallback(this.reason) while(this.rejectedCallback.length) this.rejectedCallback.shift()() } then = (fulfilledCallback, rejectedCallback) => { fulfilledCallback = fulfilledCallback ? fulfilledCallback : value => value rejectedCallback = rejectedCallback ? rejectedCallback : reason => {throw reason} let promise2 = new MyPromise((resolve, reject) => { //判斷狀態 if(this.status === FULFILLED){ setTimeout(() => { try { //判斷x 傳過來的可能是promise,先檢視promise返回的結果,在決定是用resolve還是reject, //如果是普通值,直接呼叫resolve let x = fulfilledCallback(this.value) //外面載入完,才能獲取到promise2,用非同步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else if(this.status === REJECTED){ setTimeout(() => { try { //判斷x 傳過來的可能是promise,先檢視promise返回的結果,在決定是用resolve還是reject, //如果是普通值,直接呼叫resolve let x = rejectedCallback(this.reason) //外面載入完,才能獲取到promise2,用非同步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }else{ //等待狀態 this.fulfilledCallback.push(() => { setTimeout(() => { try { //判斷x 傳過來的可能是promise,先檢視promise返回的結果,在決定是用resolve還是reject, //如果是普通值,直接呼叫resolve let x = fulfilledCallback(this.value) //外面載入完,才能獲取到promise2,用非同步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); this.rejectedCallback.push(() => { setTimeout(() => { try { //判斷x 傳過來的可能是promise,先檢視promise返回的結果,在決定是用resolve還是reject, //如果是普通值,直接呼叫resolve let x = rejectedCallback(this.reason) //外面載入完,才能獲取到promise2,用非同步解決 resolvePromise(promise2,x,resolve, reject) } catch (error) { reject(error) } },0) }); } }) return promise2 } static all (array) { let result= [] let index = 0; return new MyPromise((resolve, reject) => { function addData (key, value) { result[key] = value index++ if (index === array.length) { resolve(result) } } for (let i = 0; i < array.length; i++) { if (array[i] instanceof MyPromise) { //promise物件 array[i].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)) } finally (callback) { return this.then(value => { return MyPromise.resolve(callback()).then(() => value) }, reason => { return MyPromise.resolve(callback()).then(() => {throw reason}) }) } catch (rejectedCallback) { return this.then(undefined, rejectedCallback) } } function resolvePromise(promise2,x,resolve, reject){ if(x === promise2){ return reject(new TypeError('啦啦啦啦')) } if(x instanceof MyPromise){ //是promise //往下直接傳 x.then(resolve,reject) }else{ //普通值 resolve(x) } } module.exports = MyPromise;