如何使用Promise

在說Promise以前,不得不說一下JavaScript的嵌套的回調函數

在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呢?

其實,Promise就是一個類,並且這個類已經成爲了ES6的標準,這個類目前在chrome3二、Opera1九、Firefox29以上的版本都已經支持了,要想在全部瀏覽器上都用上的話就看看es6-promise吧。es6

那Promise怎麼用呢?

看一段很簡單的代碼,請注意閱讀代碼中的註釋。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到底解決什麼問題?

正如上面代碼所示,筆者認爲,Promise的意義就在於 then 鏈式調用 ,它避免了異步函數之間的層層嵌套,將原來異步函數的嵌套關係 轉變爲便於閱讀和理解的 鏈式步驟關係 。ajax

Promise的主要用法就是將各個異步操做封裝成好多Promise,而一個Promise只處理一個異步邏輯。最後將各個Promise用鏈式調用寫法串聯,在這樣處理下,若是異步邏輯之間先後關係很重的話,你也不須要層層嵌套,只須要把每一個異步邏輯封裝成Promise鏈式調用就能夠了。chrome

Promise經常使用的關鍵點

在Promise定義時,函數已經執行了

Promise構造函數只接受一個參數,即帶有異步邏輯的函數。這個函數在 new Promise 時已經執行了。只不過在沒有調用 then 以前不會 resolve 或 reject。數據庫

在then中的resolve方法中如何return?

在then方法中一般傳遞兩個參數,一個 resolve 函數,一個 reject 函數。reject暫時不討論,就是出錯的時候運行的函數罷了。resolve 函數必須返回一個值才能把鏈式調用進行下去,並且這個值返回什麼是有很大講究的。json

  • resolve 返回一個新 Promise後端

返回一個新Promise以後再調用的then就是新Promise中的邏輯了。api

  • resolve 返回一個值promise

返回一個值會傳遞到下一個then的resolve方法參數中。

相關文章
相關標籤/搜索