promise方法

含義

Promise 對象用於一個異步操作的最終完成(或失敗)及其結果值的表示。簡單點說,它就是用於處理異步操作的,異步處理成功了就執行成功的操作,異步處理失敗了就捕獲錯誤或者停止後續操作。

它的一般表示形式爲:

new Promise(
    /* executor */
    function(resolve, reject) {
            //發送ajax請求,根據回調信息進行下面的判斷邏輯
        if (/* success */) {
            // ...執行代碼
            resolve();
        } else { /* fail */
            // ...執行代碼
            reject();
        }
    }
);

其中,Promise中的參數executor是一個執行器函數,它有兩個參數resolvereject。它內部通常有一些異步操作,如果異步操作成功,則可以調用resolve()來將該實例的狀態置爲fulfilled,即已完成的,如果一旦失敗,可以調用reject()來將該實例的狀態置爲rejected,即失敗的。

我們可以把Promise對象看成是一條工廠的流水線,對於流水線來說,從它的工作職能上看,它只有三種狀態,一個是初始狀態(剛開機的時候),一個是加工產品成功,一個是加工產品失敗(出現了某些故障)。同樣對於Promise對象來說,它也有三種狀態:

  1. pending
    初始狀態,也稱爲未定狀態,就是初始化Promise時,調用executor執行器函數後的狀態。
  2. fulfilled
    完成狀態,意味着異步操作成功。
  3. rejected
    失敗狀態,意味着異步操作失敗。

它只有兩種狀態可以轉化,即

  • 操作成功
    pending -> fulfilled
  • 操作失敗
    pending -> rejected

並且這個狀態轉化是單向的,不可逆轉,已經確定的狀態(fulfilled/rejected)無法轉回初始狀態(pending)。

方法

Promise.prototype.then()

Promise對象含有then方法,then()調用後返回一個Promise對象,意味着實例化後的Promise對象可以進行鏈式調用,而且這個then()方法可以接收兩個函數,一個是處理成功後的函數,一個是處理錯誤結果的函數。

如下:

var promise1 = new Promise(function(resolve, reject) {
  // 2秒後置爲接收狀態
  setTimeout(function() {
    resolve('success');
  }, 2000);     
});

promise1.then(function(data) {
  console.log(data); 
            //2000毫秒數出success後再執行下一個then
}, function(err) { console.log(err); // 不執行}).then(function(data) { // 上一步的then()方法沒有返回值 console.log('鏈式調用:' + data); // 鏈式調用:undefined }).then(function(data) { // ....});

在這裏我們主要關注promise1.then()方法調用後返回的Promise對象的狀態,是pending還是fulfilled,或者是rejected?

返回的這個Promise對象的狀態主要是根據promise1.then()方法返回的值,大致分爲以下幾種情況:

  1. 如果then()方法中返回了一個參數值,那麼返回的Promise將會變成接收狀態。
  2. 如果then()方法中拋出了一個異常,那麼返回的Promise將會變成拒絕狀態。
  3. 如果then()方法調用resolve()方法,那麼返回的Promise將會變成接收狀態。
  4. 如果then()方法調用reject()方法,那麼返回的Promise將會變成拒絕狀態。
  5. 如果then()方法返回了一個未知狀態(pending)的Promise新實例,那麼返回的新Promise就是未知狀態。
  6. 如果then()方法沒有明確指定的resolve(data)/reject(data)/return data時,那麼返回的新Promise就是接收狀態,可以一層一層地往下傳遞。

轉換實例如下:

var promise2 = new Promise(function(resolve, reject) {
  // 2秒後置爲接收狀態
  setTimeout(function() {
    resolve('success');
  }, 2000);
});

promise2
  .then(function(data) {
    // 上一個then()調用了resolve,置爲fulfilled態
    console.log('第一個then');
    console.log(data);
    return '2';
  })
  .then(function(data) {
    // 此時這裏的狀態也是fulfilled, 因爲上一步返回了2
    console.log('第二個then');
    console.log(data);  // 2

    return new Promise(function(resolve, reject) {
      reject('把狀態置爲rejected error'); // 返回一個rejected的Promise實例
    });
  }, function(err) {
    // error
  })
  .then(function(data) {
    /* 這裏不運行 */
    console.log('第三個then');
    console.log(data);
    // ....
  }, function(err) {
    // error回調
    // 此時這裏的狀態也是fulfilled, 因爲上一步使用了reject()來返回值
    console.log('出錯:' + err); // 出錯:把狀態置爲rejected error
  })
  .then(function(data) {
    // 沒有明確指定返回值,默認返回fulfilled
    console.log('這裏是fulfilled態');
});

Promise.prototype.catch()

catch()方法和then()方法一樣,都會返回一個新的Promise對象,它主要用於捕獲異步操作時出現的異常。因此,我們通常省略then()方法的第二個參數,把錯誤處理控制權轉交給其後面的catch()函數,如下:

var promise3 = new Promise(function(resolve, reject) {
  setTimeout(function() {
    reject('reject');
  }, 2000);
});

promise3.then(function(data) {
  console.log('這裏是fulfilled狀態'); // 這裏不會觸發
  // ...
}).catch(function(err) {
  // 最後的catch()方法可以捕獲在這一條Promise鏈上的異常
  console.log('出錯:' + err); // 出錯:reject
});

Promise.resolve()

Promise.resolve()接受一個參數值,可以是普通的值具有then()方法的對象Promise實例。正常情況下,它返回一個Promise對象,狀態爲fulfilled。但是,當解析時發生錯誤時,返回的Promise對象將會置爲rejected態。如下:

// 參數爲普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {
  console.log(data); // 5
});


// 參數爲含有then()方法的對象
var obj = {
  then: function() {
    console.log('obj 裏面的then()方法');
  }
};

var p5 = Promise.resolve(obj);
p5.then(function(data) {
  // 這裏的值時obj方法裏面返回的值
  console.log(data); // obj 裏面的then()方法
});


// 參數爲Promise實例
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);

p7.then(function(data) {
  // 這裏的值時Promise實例返回的值
  console.log(data); // 7
});

// 參數爲Promise實例,但參數是rejected態
var p8 = Promise.reject(8);
var p9 = Promise.resolve(p8);

p9.then(function(data) {
  // 這裏的值時Promise實例返回的值
  console.log('fulfilled:'+ data); // 不執行
}).catch(function(err) {
  console.log('rejected:' + err); // rejected: 8
});

Promise.reject()

Promise.reject()和Promise.resolve()正好相反,它接收一個參數值reason,即發生異常的原因。此時返回的Promise對象將會置爲rejected態。如下:

var p10 = Promise.reject('手動拒絕');
p10.then(function(data) {
  console.log(data); // 這裏不會執行,因爲是rejected態
}).catch(function(err) {
  console.log(err); // 手動拒絕
}).then(function(data) {
 // 不受上一級影響
  console.log('狀態:fulfilled'); // 狀態:fulfilled
});

總之,除非Promise.then()方法內部拋出異常或者是明確置爲rejected態,否則它返回的Promise的狀態都是fulfilled態,即完成態,並且它的狀態不受它的上一級的狀態的影響。

大概常用的方法就寫那麼多,剩下的看自己實際需要再去了解。

解決Node回調地獄的不止有Promise,還有Generator和ES7提出的Async實現。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章