手寫Promise - 實現一個基礎的Promise
手寫Promise - 實例方法catch、finally
手寫Promise - 經常使用靜態方法all、any、resolve、reject、racejavascript
上一篇文章手寫了一個基礎的Promise,咱們繼續來完善它,爲其添加常常用到的catch和finally方法java
catch() 方法返回一個Promise,而且處理拒絕的狀況。咱們知道then方法的第二個參數其實就是幹這個用的,catch只是一個別名。segmentfault
finally() 方法返回一個Promise。在promise結束時,不管結果是fulfilled或者是rejected,都會執行指定的回調函數。和catch同樣,也只是對then的一個簡寫,至關因而傳入的函數既是onFulfilled也是onRejected。數組
有一點須要注意,finally和catch方法只是then的一個別名,實際上返回的仍是一個promise,徹底能夠這樣寫:promise.then().finally().then().catch().then()
promise
咱們把上一章節的代碼拷過來,而後向裏面添加catch和finally方法。函數
class WPromise { static pending = 'pending'; static fulfilled = 'fulfilled'; static rejected = 'rejected'; constructor(executor) { this.status = WPromise.pending; // 初始化狀態爲pending this.value = undefined; // 存儲 this._resolve 即操做成功 返回的值 this.reason = undefined; // 存儲 this._reject 即操做失敗 返回的值 // 存儲then中傳入的參數 // 至於爲何是數組呢?由於同一個Promise的then方法能夠調用屢次 this.callbacks = []; executor(this._resolve.bind(this), this._reject.bind(this)); } // onFulfilled 是成功時執行的函數 // onRejected 是失敗時執行的函數 then(onFulfilled, onRejected) { // 返回一個新的Promise return new WPromise((nextResolve, nextReject) => { // 這裏之因此把下一個Promsie的resolve函數和reject函數也存在callback中 // 是爲了將onFulfilled的執行結果經過nextResolve傳入到下一個Promise做爲它的value值 this._handler({ nextResolve, nextReject, onFulfilled, onRejected }); }); } // catch方法只有一個參數用於處理錯誤的狀況 catch(onRejected) { return this.then(null, onRejected); } finally(onFinally) { return this.then(onFinally, onFinally); } _resolve(value) { // 處理onFulfilled執行結果是一個Promise時的狀況 // 這裏可能理解起來有點困難 // 當value instanof WPromise時,說明當前Promise確定不會是第一個Promise // 而是後續then方法返回的Promise(第二個Promise) // 咱們要獲取的是value中的value值(有點繞,value是個promise時,那麼內部存有個value的變量) // 怎樣將value的value值獲取到呢,能夠將傳遞一個函數做爲value.then的onFulfilled參數 // 那麼在value的內部則會執行這個函數,咱們只須要將當前Promise的value值賦值爲value的value便可 if (value instanceof WPromise) { value.then( this._resolve.bind(this), this._reject.bind(this) ); return; } this.value = value; this.status = WPromise.fulfilled; // 將狀態設置爲成功 // 通知事件執行 this.callbacks.forEach(cb => this._handler(cb)); } _reject(reason) { if (reason instanceof WPromise) { reason.then( this._resolve.bind(this), this._reject.bind(this) ); return; } this.reason = reason; this.status = WPromise.rejected; // 將狀態設置爲失敗 this.callbacks.forEach(cb => this._handler(cb)); } _handler(callback) { const { onFulfilled, onRejected, nextResolve, nextReject } = callback; if (this.status === WPromise.pending) { this.callbacks.push(callback); return; } if (this.status === WPromise.fulfilled) { // 傳入存儲的值 // 未傳入onFulfilled時,將undefined傳入 const nextValue = onFulfilled ? onFulfilled(this.value) : undefined; nextResolve(nextValue); return; } if (this.status === WPromise.rejected) { // 傳入存儲的錯誤信息 // 一樣的處理 const nextReason = onRejected ? onRejected(this.reason) : undefined; nextReject(nextReason); } } }
是的,就是這麼簡單,如今來測試一下:測試
function fetchData() { return new WPromise((resolve, reject) => { setTimeout(() => { reject(1); }, 1000); }); } fetchData().finally((data) => { return data + 10; }).finally((data) => { return new WPromise((resolve, reject) => { reject(data + 10); }); }).finally((data) => { console.log(data); // 21 })
以上就是catch和finally的模擬實現,若是理解了then的工做原理的話,理解catch和finally也沒啥問題。fetch