[轉]JS - Promise使用詳解1(基本概念、使用優勢)

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規範圖解

原文:JS - Promise使用詳解1(基本概念、使用優勢)

4,目前支持Promises/A規範的庫

  • Q:能夠在NodeJS 以及瀏覽器上工做,與jQuery兼容,能夠經過消息傳遞遠程對象。
  • RSVP.js:一個輕量級的庫,它提供了組織異步代碼的工具。
  • when.js:體積小巧,使用方便。
  • NodeJS的Promise
  • jQuery 1.5:聽說是基於「CommonJS Promises/A」規範
  • WinJS / Windows 8 / Metro
 

2、使用promises的優點

1,解決回調地獄(Callback Hell)問題

(1)有時咱們要進行一些相互間有依賴關係的異步操做,好比有多個請求,後一個的請求須要上一次請求的返回結果。過去常規作法只能 callback 層層嵌套,但嵌套層數過多的話就會有 callback hell 問題。好比下面代碼,可讀性和維護性都不好的。
1
2
3
4
5
6
7
8
9
10
11
12
firstAsync( function (data){
     //處理獲得的 data 數據
     //....
     secondAsync( function (data2){
         //處理獲得的 data2 數據
         //....
         thirdAsync( function (data3){
               //處理獲得的 data3 數據
               //....
         });
     });
});
 
(2)若是使用 promises 的話,代碼就會變得扁平且更可讀了。前面提到 then 返回了一個 promise,所以咱們能夠將 then 的調用不停地串連起來。其中 then 返回的 promise 裝載了由調用返回的值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
firstAsync()
.then( function (data){
     //處理獲得的 data 數據
     //....
     return  secondAsync();
})
.then( function (data2){
     //處理獲得的 data2 數據
     //....
     return  thirdAsync();
})
.then( function (data3){
     //處理獲得的 data3 數據
     //....
});

2,更好地進行錯誤捕獲 

多重嵌套 callback 除了會形成上面講的代碼縮進問題,更可怕的是可能會形成沒法捕獲異常或異常捕獲不可控。
(1)好比下面代碼咱們使用 setTimeout 模擬異步操做,在其中拋出了個異常。但因爲異步回調中,回調函數的執行棧與原函數分離開,致使外部沒法抓住異常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function  fetch(callback) {
     setTimeout(() => {
         throw  Error( '請求失敗' )
     }, 2000)
}
 
try  {
     fetch(() => {
         console.log( '請求處理' // 永遠不會執行
     })
catch  (error) {
     console.log( '觸發異常' , error)  // 永遠不會執行
}
 
// 程序崩潰
// Uncaught Error: 請求失敗
 
(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
function  fetch(callback) {
     return  new  Promise((resolve, reject) => {
         setTimeout(() => {
              reject( '請求失敗' );
         }, 2000)
     })
}
 
 
fetch()
.then(
     function (data){
         console.log( '請求處理' );
         console.log(data);
     },
     function (reason, data){
         console.log( '觸發異常' );
         console.log(reason);
     }
);

固然咱們在 catch 方法中處理 reject 回調也是能夠的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function  fetch(callback) {
     return  new  Promise((resolve, reject) => {
         setTimeout(() => {
              reject( '請求失敗' );
         }, 2000)
     })
}
 
 
fetch()
.then(
     function (data){
         console.log( '請求處理' );
         console.log(data);
     }
)
. catch ( function (reason){
     console.log( '觸發異常' );
     console.log(reason);
});


原文出自:www.hangge.com  轉載請保留原文連接:https://www.hangge.com/blog/cache/detail_1635.htmlhtml

相關文章
相關標籤/搜索