JS_是時候使用promise了

1. 異步編程

JS是單線程執行了,經過event loop實現了非阻塞的I/O。編程中常常用異步回調函數的方式處理I/O的反饋結果(網絡請求,用戶交互事件)。如分別發送兩個請求:html

function xhrRequest(url, callback) {
    setTimeout(function(){ // 用setTimeout模擬異步請求
        callback();
    }, 0)
}

xhrRequest('/index', function(){
    console.log('request /index done');
})
xhrRequest('/list', function(){
    console.log('request /list done');
})

但若是想在請求index後再請求list怎麼辦呢?,可能會這樣寫:es6

xhrRequest('/index', function(){
    console.log('request /index done');
    xhrRequest('/list', function(){ // 回調函數裏,再次回調
        console.log('request /list done');
    })
})

可是若是有3個或4個異步請求有前後依賴怎麼呢?回調函數會一直嵌套回調函數(callback hell),代碼看起來亂糟糟的,而且很差維護。事件模式也不能很好處理這些,急需其餘能下降異步編程複雜性的方式。編程

2. promise模式

2.1 promise A+

Promise已是個標準了,最新的是Promise A+標準。標準中給Promise的定義是:"A promise represents the eventual result of an asynchronous operation"。即Promise表示一個異步操做的最終結果。主要經過Promise對象的then方法和Promise對象進行交互:註冊失敗,成功回調函數,而且失敗回調函數接收一個失敗緣由(reason)參數,成功回調函數接收一個值(value)參數。Promise A+標準主要是定義then方法的規範。segmentfault

2.1.1 Promise對象狀態

Promise對象有三種狀態:Pending(待定),Fullfilled(已完成),Rejected(已拒絕)。
A:Pending的Promise對象能夠轉成Fullfilled或者Rejected
B:Fullfilled的Promise對象不能轉成其餘狀態,而且必須含有一個值(value),該值不能變。
C:Rejected的Promise對象不能轉成其餘狀態,而且必須含有一個緣由對象(reason)表示失敗的緣由,該值不能變。promise

2.1.2 then(onFullfilled, onRejected)方法

then方法的規範不少,認真讀讀標準。但要主要下面幾點:
A:每一個回調函數只能執行一次。
B:屢次調用then方法,能夠註冊多個回調函數,回調函數的調用順序取決於調用then方法的順序。若是Promise對象已經處於fullfilled/ rejected狀態,調用then方法會當即執行onfullfilled/onRejected回調函數。
C:then方法必須返回個Promise對象: Promise2 = Promse1.then(onFullfilled, onRejected)。但沒規定Promise1和Promise2是否相等,這個要看具體的實現了。網絡

2.1.3 then鏈

then方法返回一個Promise對象,這樣就構成一個then鏈。前面的Promise對象的狀態變化對後面的Promise對象的狀態的影響稱爲Promise解決程序(The Promise Resolution Procedure)。框架

2.2 Promise標準實現

實現Promise標準的庫和框架有不少了,jQuery,Zeptojs,ES6等。好多庫中Promise實現叫Deferred,Deferred對象是用來操做Promise對象(修改Promise對象狀態),而Promise對象自己只提供then方法添加回調函數(以及其餘添加回調函數的方法),不提供操做Promise對象的方法,這樣設計使得Promise對象對外不可修改,詳細參考ZeptoJS Deferred實現。異步

2.3 爲何Promise模式重要

Promise是把相似的異步處理對象和處理規則進行規範化, 並按照採用統一的接口來編寫,而採起規定方法以外的寫法都會出錯。這樣更有利理解,維護。將複雜的異步處理輕鬆地進行模式化。async

參考

  1. 異步編程
  2. Promise A+標準
  3. promises 很酷,但不少人並無理解就在用了
相關文章
相關標籤/搜索