function isFunction(fn){ return Object.prototype.toString.call(fn) === '[object Function]'; } let ST = { pending: 0, resolved: 1, rejected: 2 } function Promise(fn){ let self = this; self.status = ST.pending; self.value = ''; self.reason = ''; self.resolveFns = []; self.rejectFns = []; //setTimeout延遲執行,將reslove執行放在下個循環,保證then方法先於它執行 function resolve(val){ setTimeout(() => { if(self.status == ST.pending){ self.status = ST.resolved; self.value = val; //用數組保存回調,是爲了處理一個promise掛載多個then的狀況 //注意不是鏈式,這種場景不多出現 /* 形如: promise.then(resolve1,reject1) promise.then(resolve2,reject2) promise.then(resolve3,reject3) */ //在鏈式調用中,該數組一般只會有一個項,就是當前promise的下一個then裏面的resolve函數 //且每次執行,一般都是一個新Promise的resolve數組 self.resolveFns.forEach(fn => fn()); } }) } function reject(val){ setTimeout(() => { if(self.status == ST.pending){ self.status = ST.rejected; self.reason = val; self.rejectFns.forEach(fn => fn()); } }) } //執行出問題,直接reject,Promise的錯誤默認不會拋出到全局 try{ fn(resolve,reject); } catch(err){ reject(err); } } Promise.prototype.then = function(onResolve,onReject){ let self = this; //then每次執行都返回一個新的Promise,then方法要處理前一個promise的三種狀態 return new Promise(function(resolve,reject){ function handle(value,thenFn){ let res = isFunction(thenFn) && thenFn(value) || value; if(res instanceof Promise){ res.then(resolve,reject); } else{ resolve(res); } } //處理三種狀態 //fn函數體裏,若是有錯誤; 會執行try catch裏的 reject方法,執行then this.state就是rejected //若是沒錯誤且沒異步,resolve this.state就是resolved //若是沒錯誤且有異步,this.state就是pending if(self.status == ST.pending){ self.resolveFns.push(resloveHandle); self.rejectFns.push(rejectHandle); } else if(self.status == ST.resolved){ self.handle(self.value,onResolve); } else if(this.status == ST.rejected){ self.handle(self.reason,onReject); } }) } Promise.prototype.catch = function(onReject){ return this.then(undefined, onReject); } //finally不是promise的末尾,後面還能夠有then,因此value和reason必須能夠向下傳遞 Promise.prototype.finally = function(fn){ let P = this.constructor; return this.then( value => P.resolve(fn()).then(() => value), reason => P.resolve(fn()).then(() => throw reason); ) } //done做爲promise的末尾,用於收集全部可能的報錯,catch方法捕捉全部錯誤,並拋出 Promise.prototype.done = function(resolve,reject){ return this.then(resolve, reject).catch(function(reason){ setTimeout(function(){ throw reason; }); }) } Promise.resolve = function(val){ return new Promise((resolve) => { resolve(val); }) } Promise.reject = function(val){ return new Promise((resolve,reject) => { reject(val); }) } Promise.race = function(promises){ let len = promises.length; return new Promise(function(resolve,reject){ while(len--){ promises[len].then(resolve,reject); } }) } Promise.all = function(promises){ let len = promises.length, results = []; return new Promise(function(resolve,reject){ //用一個數組收集單個promise執行後的結果,收集滿數組全部結果,即是全部執行成功 function reslove(index){ return function(value){ results[index] = value; if(results.length == len){ reslove(results); } } } while(len--){ promises[len].then(resolve(len),reject); } }) }