1. 程式人生 > >Promise對象解讀

Promise對象解讀

reject 正常 第一個 裏的 流程 eject 有意 fail style

首先強調的是“Promise”是對象,也就是說與其他JavaScript對象的用法,沒有什麽兩樣;其次,它起到代理作用(proxy),充當異步操作與回調函數之間的中介。它使得異步操作具備同步操作的接口,使得程序具備正常的同步運行的流程,回調函數不必再一層層嵌套。

Promise 對象是 CommonJS 工作組提出的一種規範,目的是為異步操作提供統一接口,簡單說,它的思想是,每一個異步任務立刻返回一個Promise對象,由於是立刻返回,所以可以采用同步操作的流程。這個Promises對象有一個then方法,允許指定回調函數,在異步任務完成後調用。

前文說了Promise對象提供異步操作接口,簡而言之就是:執行異步任務時返回一個Promise對象,並且Promise對象只有三種狀態:

  1.異步操作“未完成”(pending)

  2.異步操作“已完成”(resolved,又稱fulfilled)

  3.異步操作“失敗”(rejected)

三種狀態的轉換只有兩種途徑: 異步操作從“未完成”到“已完成” => 異步操作從“未完成”到“失敗”。所以這種變化只能發生一次,一旦當前狀態變為“已完成”或“失敗”,就意味著不會再有新的狀態變化了。因此,Promise對象的最終結果只有兩種:{

  • 異步操作成功,Promise對象傳回一個值,狀態變為resolved
  • 異步操作失敗,Promise對象拋出一個錯誤,狀態變為rejected

Promise對象使用then

方法添加回調函數。then方法可以接受兩個回調函數,第一個是異步操作成功時(變為resolved狀態)時的回調函數,第二個是異步操作失敗(變為rejected)時的回調函數(可以省略)。一旦狀態改變,就調用相應的回調函數。

那麽promise對象是怎麽生成的呢?

其實ES6提供了原生的Promise構造函數,用來生成Promise實例。下面代碼創造了一個Promise實例。(跟聲明對象new一樣的方式)

var promise = new Promise(function(resolve, reject) {
  // 異步操作的代碼

  if (/* 異步操作成功 */){
    resolve(value);
  } 
else { reject(error); } });

resolve函數的作用是,將Promise對象的狀態從“未完成”變為“成功”(即從Pending變為Resolved),在異步操作成功時調用,並將異步操作的結果,作為參數傳遞出去;reject函數的作用是,將Promise對象的狀態從“未完成”變為“失敗”(即從Pending變為Rejected),在異步操作失敗時調用,並將異步操作報出的錯誤,作為參數傳遞出去。

Promise實例生成以後,可以用then方法分別指定Resolved狀態和Reject狀態的回調函數。

po.then(function(value) {
  // success
}, function(value) {
  // failure
});

Promise 封裝的代碼肯定是同步的, 那麽這個 then 的執行是異步的嗎?  可以通過以下這個有意思的小例子可以知道Promise對象的執行順序

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function executor(resolve) {
  console.log(2);
  for( var i=0 ; i<10000 ; i++ ) {
    i == 9999 && resolve();
  }
  console.log(3);
}).then(function() {
  console.log(4);
});
console.log(5);


==》》2 3 5 4 1

以上是我看一篇博文裏的一段代碼(出自),可以參考一下奧

Promise對象解讀