在JavaScript語言中,不管是寫瀏覽器端的各類事件處理回調、ajax回調,仍是寫Node.js上的業務邏輯,不得不面對的問題就是各類回調函數。回調函數少了還好,一旦多了起來並且必須講究執行順序的話,回調函數開始嵌套,那代碼的噁心程度是至關不符合常人的線性思惟的。git
1 // 就像下面這樣: 2 // 你不在意下面這三個ajax的執行順序還好 3 // 若是你在意順序呢? 4 $.get('url', function(){ 5 6 }, 'json'); 7 $.get('url1', function(){ 8 9 }, 'json'); 10 $.get('url2', function(){ 11 12 }, 'json'); 13 14 // 就像這樣? 15 $.get('url', function(){ 16 $.get('url1', function(){ 17 $.get('url2', function(){ 18 19 }, 'json'); 20 }, 'json'); 21 }, 'json'); 22 23 24 // 下面是我最近寫的一段Node.js的代碼 25 // 其實這個嵌套也不算多 26 // 若是業務邏輯至關複雜起來呢? 27 // 嵌套20 30層? 28 var adminIndex = function(params, callback){ 29 storeAdmin.getApiTokens(function(err, tokens){ 30 if ( err ) { callback(err); return; } 31 storeAdmin.getApiServices(function(err, apiServices){ 32 if ( err ) { callback(err); return; } 33 storeAdmin.getSocketioServices(function(err, socketioServices){ 34 if ( err ) { callback(err); return; } 35 callback(0, { 36 status : true, 37 data : { 38 api_tokens : tokens, 39 api_services : apiServices, 40 socketio_services : socketioServices 41 } 42 }); 43 }); 44 }); 45 }); 46 };
其實,Promise就是一個類,並且這個類已經成爲了ES6的標準,這個類目前在chrome3二、Opera1九、Firefox29以上的版本都已經支持了,要想在全部瀏覽器上都用上的話就看看es6-promise吧。es6
看一段很簡單的代碼,請注意閱讀代碼中的註釋。github
1 var val = 1; 2 3 // 咱們假設step1, step2, step3都是ajax調用後端或者是 4 // 在Node.js上查詢數據庫的異步操做 5 // 每一個步驟都有對應的失敗和成功處理回調 6 // 需求是這樣,step一、step二、step3必須按順序執行 7 function step1(resolve, reject) { 8 console.log('步驟一:執行'); 9 if (val >= 1) { 10 resolve('Hello I am No.1'); 11 } else if (val === 0) { 12 reject(val); 13 } 14 } 15 16 function step2(resolve, reject) { 17 console.log('步驟二:執行'); 18 if (val === 1) { 19 resolve('Hello I am No.2'); 20 } else if (val === 0) { 21 reject(val); 22 } 23 } 24 25 function step3(resolve, reject) { 26 console.log('步驟三:執行'); 27 if (val === 1) { 28 resolve('Hello I am No.3'); 29 } else if (val === 0) { 30 reject(val); 31 } 32 } 33 34 new Promise(step1).then(function(val){ 35 console.info(val); 36 return new Promise(step2); 37 }).then(function(val){ 38 console.info(val); 39 return new Promise(step3); 40 }).then(function(val){ 41 console.info(val); 42 return val; 43 }).then(function(val){ 44 console.info(val); 45 return val; 46 }); 47 48 // 執行以後將會打印 49 步驟一:執行 50 Hello I am No.1 51 步驟二:執行 52 Hello I am No.2 53 步驟三:執行 54 Hello I am No.3 55 Hello I am No.3
正如上面代碼所示,筆者認爲,Promise的意義就在於 then 鏈式調用 ,它避免了異步函數之間的層層嵌套,將原來異步函數的嵌套關係 轉變爲便於閱讀和理解的 鏈式步驟關係 。ajax
Promise的主要用法就是將各個異步操做封裝成好多Promise,而一個Promise只處理一個異步邏輯。最後將各個Promise用鏈式調用寫法串聯,在這樣處理下,若是異步邏輯之間先後關係很重的話,你也不須要層層嵌套,只須要把每一個異步邏輯封裝成Promise鏈式調用就能夠了。chrome
Promise構造函數只接受一個參數,即帶有異步邏輯的函數。這個函數在 new Promise
時已經執行了。只不過在沒有調用 then
以前不會 resolve 或 reject。數據庫
在then方法中一般傳遞兩個參數,一個 resolve
函數,一個 reject
函數。reject
暫時不討論,就是出錯的時候運行的函數罷了。resolve
函數必須返回一個值才能把鏈式調用進行下去,並且這個值返回什麼是有很大講究的。json
resolve
返回一個新 Promise後端
返回一個新Promise以後再調用的then就是新Promise中的邏輯了。api
resolve
返回一個值promise
返回一個值會傳遞到下一個then的resolve方法參數中。