標籤(空格分隔): ES6 Promisejavascript
本文原創,如需轉載請註明出處前端
作了Sudoku項目後,很頭疼的問題就是代碼維護,很大一部分緣由是回調嵌套太多,影響代碼的可讀性,增長了維護難度,尤爲是後端的數據庫操做,用nodeJs一般會寫許多回調嵌套。此次終於打算揭竿起義。java
第二次修改,廢話很少說,直接進入正題
先看下面這段代碼node
function do(){ //查找數據庫 setTimeout(()=>{ console.log('收到數據'); //修改字段,並保存 setTimeout(()=>{ console.log('保存成功') //發送響應給前端 },1000) setTimeout },1000) } do()
模擬了很是簡單的一個從前端接受請求到發送響應回到前端的過程,
這個代碼是很是簡單的,不過看起來並非,並且一旦需求更復雜,
這樣風格的代碼確定會讓我很是頭疼es6
- 每一個異步過程獨立成塊,再也不是嵌套風格
- 異步返回結果的處理過程獨立於異步過程
- 可伸縮,直接擴展異步結果處理過程,並不與以前的混在一塊兒,實現細分,獨立成塊
- 每一個異步過程存在依賴
好吧,發現promise知足個人全部需求,拿來現成用?這一點都很差玩
,因此研究了一下promise的用法,下面是我簡易的需求說明數據庫
- 每一個promise實例 resolve動做 reject動做
- promise實例 then方法註冊resolve回調,reject回調
- A實例執行完回調,then()會返回一個B實例
- B實例跟A同樣,一樣有 resolve動做 reject動做
- 調用B的then()方法一樣會註冊resolve回調,reject回調
- 影響B動做的因素有4個(下面詳細講解)
- 有catch同then同樣,可是隻能註冊一個錯誤回調
- a實例如過程上依賴於另一個b實例,則可被當作其resolve參數傳遞,而且b實例成功好事滾粗依賴於 a 的狀態
- 一旦實例狀態發生改變,狀態不會再改變
是:B執行reject動做 否:B執行resolve動做
是:回到1. 、 否:B執行reject動做
是:回到1 否: B執行resolve動做
C resolve: B resolve C reject: B reject
Promise實例全部的屬性後端
class Promise{ //構造函數 fn爲構建實例的異步過程 constructor(fn){ //必須爲函數類型 if(typeof fn !== 'function') throw new Error('not a function'); this.success = []; this.sucArg = null; this.fail = []; this.failArg = null; this.state = 0; this.parent = null; //fork promise分支 this.fork = []; //傳遞的error setTimeout(()=>{ fn(myPromise.resolve.bind(this),myPromise.reject.bind(this)) },0); } }
Promise實例的方法,then(),catch()promise
//onFulfilled成功處理函數,onRejected滾粗處理函數 then(onFulfilled,onRejected){ /*參數格式限制*/ let fork = new myPromise(()=>{}); if(typeof onFulfilled ==='function'){ this.success.push(onFulfilled); fork.forkSuc = onFulfilled; } if(typeof onRejected ==='function'){ this.fail.push(onRejected); fork.forkRej = onRejected; } this.fork.push(fork); return fork; } catch(onRejected){ //參數必須函數 let fork = new myPromise(()=>{}); if(typeof onRejected !=='function') return this; this.fail.push(onRejected); fork.forkRej = onRejected; this.fork.push(fork); return fork; }
Promise靜態方法resolve,reject異步
static resolve(value){ if(this.state!==0) return; //參數不是myPromise實例 if(value instanceof myPromise){ //如參數是一個promise實例 value.parent = this; if(value.state===1){ //實例狀態爲成功 myPromise.resolve.call(this,value.successArg); }else if(value.state===-1){ //實例狀態爲失敗 myPromise.reject.call(this,value.failArg); } }else{ if(!this.success.length){ for(let fn of this.fork){ myPromise.resolve.call(fn,value); } }else{ this.sucArg = value; let cur = 0; for(let fn of this.success){ if(this.fork.length&&fn===this.fork[cur].forkSuc){ let error,preArg,bool; try{ preArg = fn(value); if(preArg instanceof myPromise){ let index = cur; bool = true; preArg.success.push(()=>{ myPromise.resolve.call(this.fork[index],preArg.sucArg); }); preArg.fail.push(()=>{ myPromise.reject.call(this.fork[index],preArg.failArg); }) } }catch(err){ error = err||null; } if(!bool){ error? myPromise.reject.call(this.fork[cur],error): myPromise.resolve.call(this.fork[cur],preArg); } cur++; }else{ fn(value); } } } //當前promise變爲fulfilled this.state = 1; //如存在parent,則parent.resolve(value) if(this.parent) myPromise.resolve.call(this.parent,value); } } static reject(value){ if(this.state!==0) return; //參數是myPromise實例 if(value instanceof myPromise){ value.parent = this; myPromise.reject.call(this); }else{ if(!this.fail.length){ for(let fn of this.fork){ myPromise.reject.call(fn,value) } }else{ this.failArg = value; let cur = 0; for(let fn of this.fail){ if(this.fork.length&&fn===this.fork[cur].forkRej){ let error,preArg,bool; try{ preArg = fn(value); if(preArg instanceof myPromise){ let index = cur; bool = true; preArg.success.push(()=>{ myPromise.resolve.call(this.fork[index],preArg.sucArg); }); preArg.fail.push(()=>{ myPromise.reject.call(this.fork[index],preArg.failArg); }) } }catch(err){ error = err||null; } if(!bool){ error? myPromise.reject.call(this.fork[cur],error): myPromise.resolve.call(this.fork[cur],preArg); } cur++; }else{ fn(value); } } } this.state = -1; if(this.parent) myPromise.reject.call(this.parent,value); } }
好了,就這麼多,這是個簡易的Promise實現,若有錯誤,或者什麼建議
QQ:387857274歡迎討論函數