談談Promise那點事(一)

找抽的小陀螺發表於2017-09-23

談談Promise那點事(一)

隨著es6流行 Promise使用非常的廣泛 那那都是Promise 非同步請求返回一個Promise物件,Generator 中 yield 後面一般跟 Promise 物件, 等等到處都是Promise 我們真的搞明白了? 我們來簡單嘮嘮

  • Promise的規範

    1. 一個Promise 有三種狀態等待(pending)、已完成(fulfilled)、已拒絕(rejected)

      一個promise的狀態只可能從“等待”轉到“完成”態或者“拒絕”態,不能逆向轉換,同時“完成”態和“拒絕”態不能相互轉換

    2. 一個Promise 有一個then方法
      接收兩個可選函式引數onFulfilled、onRejected而且then必須返回一個promise,同一個promise的then可以呼叫多次,並且回撥的執行順序跟它們被定義時的順序一致
  • Promise的API

    1. 例項的方法
      .then(resolvedFn, rejectFn)方法 .then 為Promise新增一個狀態改變時候的回撥 返回值一個新Promise的例項
      .catch()方法 返回值也是一個Promise物件 Promise物件的錯誤具有冒泡性質 錯誤一直往後面傳遞 知道一直被這個 catch捕獲 正因為 這些例項方法都是Promise物件 所以可以通過鏈式呼叫
    2. 靜態的方法
      Promise.resolve()方法

      將物件轉為Promise物件比如

          var jsPromise = Promise.resolve($.ajax('/whatever.json'));
          Promise.resolve('foo')
          // 等價於
          new Promise(resolve => resolve('foo'))複製程式碼

      Promise.resolve() 方法引數有四種情況

      • 如果引數是Promise例項 那返回也就是就是這個例項
      • 如果返回時thenable 物件(含有then的物件) 則先將其轉換為promise物件,然後立即執行這個物件的then方法

          let thenable = {
           then: function(resolve, reject) {
             resolve(42);
           }
          }
        
         let p1 = Promise.resolve(thenable);
         p1.then(function(value) {
           console.log(value);  // 42
         });複製程式碼
      • 如果引數是個原始值,則返回一個promise物件,狀態為resolved,這個原始值會傳遞給回撥

         var p = Promise.resolve('Hello');
        
         p.then(function (s){
           console.log(s)
         });
         // Hello複製程式碼
      • 沒有引數,直接返回一個resolved的Promise物件

         var p = Promise.resolve();
         p.then(function () {
           // ...
         });
         這裡p  就是Promise物件複製程式碼

      Promise.reject()方法
      同上,不同的是返回的promise物件的狀態為rejected

      Promise.all()方法
      Promise.all方法用於將多個 Promise 例項,包裝成一個新的 Promise 例項。

      var p = Promise.all([p1, p2, p3]);複製程式碼

      這裡引數是陣列 p123都是Promise例項 如果不是Promise例項 會用到Promise.resolve() 轉為Promise例項

      1. 如果全部成功,狀態變為resolved,返回值將組成一個陣列傳給回撥
      2. 只要有一個失敗,狀態就變為rejected,返回值將直接傳遞給回撥
      3. 返回值也是個Promise例項
      // 生成一個Promise物件的陣列
      var promises = [2, 3, 5, 7, 11, 13].map(function (id) {
       return getJSON('/post/' + id + ".json");
      });
      
      Promise.all(promises).then(function (posts) {
       // ...
      }).catch(function(reason){
       // ...
      });複製程式碼

      上面解釋下 Promises是包含6個promise例項的陣列 這6個都變成都成功fulfilled 或者其中一個失敗rejected 都會呼叫all方法 後面回撥函式
      這裡注意下若果自己定義了catch 捕獲 那麼在all裡面是捕獲不到的

Promise.race()方法

  1. 同上,區別是,只要有一個Promise例項率先發生變化(無論是狀態變成resolved還是rejected)都觸發then中的回撥,返回值將傳遞給回撥
  2. race()的返回值也是新的Promise物件

Promise初嘗一
參考連結ECMAScript 6 入門(阮一峰)

相關文章