基於ES6語法手寫promise A+ 規範,源碼實現 class Promise { constructor(excutorCallBack) { this.status = 'pending'; this.value = undefined; this.fulfilledAry = []; th ...
基於ES6語法手寫promise A+ 規範,源碼實現
class Promise { constructor(excutorCallBack) { this.status = 'pending'; this.value = undefined; this.fulfilledAry = []; this.rejectedAry = []; //=>執行EXCUTOR(異常捕獲) let resolveFn = result => { let timer = setTimeout(() => { clearTimeout(timer); if (this.status !== 'pending') return; this.status = 'fulfilled'; this.value = result; this.fulfilledAry.forEach(item => item(this.value)); }, 0); }; let rejectFn = reason => { let timer = setTimeout(() => { clearTimeout(timer); if (this.status !== 'pending') return; this.status = 'rejected'; this.value = reason; this.rejectedAry.forEach(item => item(this.value)); }, 0); }; try { excutorCallBack(resolveFn, rejectFn); } catch (err) { //=>有異常信息按照REJECTED狀態處理 rejectFn(err); } } then(fulfilledCallBack, rejectedCallBack) { //=>處理不傳遞的狀況 typeof fulfilledCallBack !== 'function' ? fulfilledCallBack = result => result : null; typeof rejectedCallBack !== 'function' ? rejectedCallBack = reason => { throw new Error(reason instanceof Error ? reason.message : reason); } : null; //=>返回一個新的PROMISE實例 return new Promise((resolve, reject) => { this.fulfilledAry.push(() => { try { let x = fulfilledCallBack(this.value); x instanceof Promise ? x.then(resolve, reject) : resolve(x); } catch (err) { reject(err); } }); this.rejectedAry.push(() => { try { let x = rejectedCallBack(this.value); x instanceof Promise ? x.then(resolve, reject) : resolve(x); } catch (err) { reject(err); } }); }); } catch(rejectedCallBack) { return this.then(null, rejectedCallBack); } static all(promiseAry = []) {//=>Promise.all() return new Promise((resolve, reject) => { //=>INDEX:記錄成功的數量 RESULT:記錄成功的結果 let index = 0, result = []; for (let i = 0; i < promiseAry.length; i++) { //=>promiseAry[i]: //每一個需要處理的PROMISE實例 promiseAry[i].then(val => { index++; result[i] = val;//=>索引需要和promiseAry對應上,保證結果的順序和數組順序一致 if (index === promiseAry.length) { resolve(result); } }, reject); } }); } } module.exports = Promise;