JS - Promise使用詳解1(基本概念、使用優點)
一、promises相關概念
promises 的概念是由 CommonJS 小組的成員在 Promises/A 規範中提出來的。
1,then()方法介紹
根據 Promise/A 規範,promise 是一個物件,只需要 then 這一個方法。then 方法帶有如下三個引數:
- 成功回撥
- 失敗回撥
- 前進回撥(規範沒有要求包括前進回撥的實現,但是很多都實現了)。
一個全新的 promise 物件從每個 then 的呼叫中返回。
2,Promise物件狀態
Promise 物件代表一個非同步操作,其不受外界影響,有三種狀態:
- Pending(進行中、未完成的)
- Resolved(已完成,又稱 Fulfilled)
- Rejected(已失敗)。
(1)promise 從未完成的狀態開始,如果成功它將會是完成態,如果失敗將會是失敗態。
(2)當一個 promise 移動到完成態,所有註冊到它的成功回撥將被呼叫,而且會將成功的結果值傳給它。另外,任何註冊到 promise 的成功回撥,將會在它已經完成以後立即被呼叫。
(3)同樣的,當一個 promise 移動到失敗態的時候,它呼叫的是失敗回撥而不是成功回撥。
(4)對包含前進特性的實現來說,promise 在它離開未完成狀態以前的任何時刻,都可以更新它的 progress。當 progress 被更新,所有的前進回撥(progress callbacks)會被傳遞以 progress 的值,並被立即呼叫。前進回撥被以不同於成功和失敗回撥的方式處理;如果你在一個 progress 更新已經發生以後註冊了一個前進回撥,新的前進回撥只會在它被註冊以後被已更新的 progress 呼叫。
(5)注意:只有非同步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。
3,Promise/A規範圖解
4,目前支援Promises/A規範的庫
- Q:可以在NodeJS 以及瀏覽器上工作,與jQuery相容,可以通過訊息傳遞遠端物件。
- RSVP.js:一個輕量級的庫,它提供了組織非同步程式碼的工具。
- when.js:體積小巧,使用方便。
- NodeJS的Promise
- jQuery 1.5:據說是基於“CommonJS Promises/A”規範
- WinJS / Windows 8 / Metro
二、使用promises的優勢
1,解決回撥地獄(Callback Hell)問題
(1)有時我們要進行一些相互間有依賴關係的非同步操作,比如有多個請求,後一個的請求需要上一次請求的返回結果。過去常規做法只能 callback 層層巢狀,但巢狀層數過多的話就會有 callback hell 問題。比如下面程式碼,可讀性和維護性都很差的。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
(2)如果使用 promises 的話,程式碼就會變得扁平且更可讀了。前面提到 then 返回了一個 promise,因此我們可以將 then 的呼叫不停地串連起來。其中 then 返回的 promise 裝載了由呼叫返回的值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
2,更好地進行錯誤捕獲
多重巢狀 callback 除了會造成上面講的程式碼縮排問題,更可怕的是可能會造成無法捕獲異常或異常捕獲不可控。
(1)比如下面程式碼我們使用 setTimeout 模擬非同步操作,在其中丟擲了個異常。但由於非同步回撥中,回撥函式的執行棧與原函式分離開,導致外部無法抓住異常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
(2)如果使用 promises 的話,通過 reject 方法把 Promise 的狀態置為 rejected,這樣我們在 then 中就能捕捉到,然後執行“失敗”情況的回撥。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|
當然我們在 catch 方法中處理 reject 回撥也是可以的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|