參考Promise 的 官方規範 https://promisesaplus.com/ Promise 其實就是一個狀態機 它只有兩種狀態變化 pending =》 fulfilled pending =》 rejected 並且狀態一旦發生變化後就不會再改變 我們用es5來實現下 先寫個架子, 並 ...
參考Promise 的 官方規範 https://promisesaplus.com/
Promise 其實就是一個狀態機
它只有兩種狀態變化 pending =》 fulfilled
pending =》 rejected
並且狀態一旦發生變化後就不會再改變
我們用es5來實現下
先寫個架子, 並測試下:
function myPromise(executor) { var _this = this; // 保存當前的函數上下文 _this.status = 'pending'; // 初始狀態 _this.resolveValue = null; // resolve初始值 _this.rejectValue = null; // reject初始值 function resolve(value) { if (_this.status == 'pending') { _this.status = 'Fulfilled'; _this.resolveValue = value; } } function reject(reason) { if (_this.status == 'pending') { _this.status = 'Fulfilled'; _this.rejectValue = reason; } } try { // 捕獲錯誤 executor(resolve, reject) } catch (e){ reject(e); } } myPromise.prototype.then = function (onFulfilled, onRejected) { var _this = this; if (_this.status == 'Fulfilled') { onFulfilled(_this.resolveValue) } if (_this.status == 'Rejected') { onRejected(_this.rejectValue) } }; var p = new myPromise((resolve, reject) => { resolve('I am handsome'); throw Error('捕獲錯誤') }); p.then((data) => { console.log(data) }, (err) => { console.log(err) } );
結果:
它先執行resolve 狀態 變為 Fulfilled ,
然後報錯 ,執行reject , 由於此時狀態不是pending, 狀態還是Fulfilled
Promise的核心是處理非同步,
現在我們的代碼並不能等待狀態的改變,
接下來我們加上處理非同步操作的功能, 並測試下
function myPromise(executor) { var _this = this; // 保存當前的函數上下文 _this.status = 'pending'; // 初始狀態 _this.resolveValue = null; // resolve初始值 _this.rejectValue = null; // reject初始值 _this.resolveCallbackList = []; // 存resolve的回調 _this.rejectCallbackList = []; // 存reject的回調 function resolve(value) { if (_this.status == 'pending') { _this.status = 'Fulfilled'; _this.resolveValue = value; // 狀態改變執行存的回調 _this.resolveCallbackList.forEach(function(ele){ if (ele) { ele(); } }) } } function reject(reason) { if (_this.status == 'pending') { _this.status = 'Rejected'; _this.rejectValue = reason; // 狀態改變執行存的回調 _this.rejectCallbackList.forEach(function(ele){ if (ele) { ele(); } }) } } try { // 捕獲錯誤 executor(resolve, reject) } catch (e){ reject(e); } } myPromise.prototype.then = function (onFulfilled, onRejected) { var _this = this; if (_this.status == 'Fulfilled') { onFulfilled(_this.resolveValue) } if (_this.status == 'Rejected') { onRejected(_this.rejectValue) } // 等待狀態時把回調存起來,狀態改變再觸發 if (_this.status == 'pending') { _this.resolveCallbackList.push(function () { onFulfilled(_this.resolveValue) }); _this.rejectCallbackList.push(function () { onRejected(_this.rejectValue) }); } }; var p = new myPromise((resolve, reject) => { setTimeout(() => { resolve('I am handsome'); }, 0); // throw Error('捕獲錯誤') }); p.then((data) => { console.log(data) }, (err) => { console.log(err) } );
結果: