es6 Promise筆記

promise簡介

  • Promise是異步編程的一種解決方案ajax

  • 異步編程有如下四種:編程

    • Promise
    • 回調函數
    • 事件
    • 訂閱發佈模式
  • 特色json

    • Promise對象的狀態不受外界的影響,只有異步操做的結果能夠影響其狀態,其狀態有:
      • pending(進行中)
      • fulfilled(已成功)
      • rejected (失敗)
    • 一旦狀態肯定,就不會變化
      • Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。只要這兩種狀況發生, 狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱爲 resolved(已定型)
  • 缺點:數組

    • 一旦新建,Promise就會執行,而且沒法中途取消
    • 若沒有設置回調函數,Promise內部拋出的錯誤沒法反應到外部
    • pending狀態時,沒法得知是剛開始仍是快結束了

基本用法

  • Promise對象是一個構造函數,其接受一個函數爲參數,該函數有兩個參數,分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。
    let myPromise = new Promise(function (resolve,reject) {
        console.log('當即執行')
        if (異步操做成功) { 
            resolve(value)
        }else {
        reject(error)
        }
    })
    • resolve函數將Promise對象的狀態從pending變成fulfilled,並將異步操做成功的結果做爲參數傳遞出去
    • reject函數將Promise對象的狀態從pending變成rejected,並將異步操做失敗的結果做爲參數傳遞出去
  • Promise實例生成以後,經過then能夠指定resolved(fulfilled)狀態和rejected狀態的回調函數。
    // 下面舉一個簡單的ajax請求的例子
     let myPromise = new Promise(function (resolve,reject) {
            $.ajax({
            succeed:function () {
             resolve(value)
            },
            error: function () {
            reject(error)
            }
            })
         })
         myPromise.then(function (value) {
         //請求成功後續的操做,這裏也能夠作後續的異步操做
         },function (error) {
         //請求失敗後續的操做,該函數可選
         })
  • Promise一旦新建,其參數函數就會當即執行
    let promise = new Promise(function(resolve, reject) {
      console.log('Promise');
      resolve();
    });
    
    promise.then(function() {
      console.log('resolved.');//這裏是異步操做,因此是最後輸出
    });
    
    console.log('Hi!');
    
    // Promise
    // Hi!
    // resolved

Promise.prototype.then()

  • then接受兩個參數,這兩個參數是函數,第一個參數函數爲resolved狀態下的回調函數,第二個參數函數爲rejected狀態下的回調函數,且可選
  • then執行完後會返回新的Promise對象,因此支持鏈式調用,能夠有多個then,前面then的回調函數返回的結果會做爲參數傳給後面then的回調函數
    getJSON("/posts.json").then(function(json) {
        return json.post;//將json.post傳給後面的then回調函數
      }).then(function(post) {
        // ...
      });
  • 見下面例子:
    const getJSON = function(url) {
      const promise = new Promise(function(resolve, reject){
        const handler = function() {
          if (this.readyState !== 4) {
            return;
          }
          if (this.status === 200) {
            resolve(this.response);
          } else {
            reject(new Error(this.statusText));
          }
        };
        const client = new XMLHttpRequest();
        client.open("GET", url);
        client.onreadystatechange = handler;
        client.responseType = "json";
        client.setRequestHeader("Accept", "application/json");
        client.send();
    
      });
    
      return promise;
    };
      getJSON("/post/1.json").then(function(post) {
        return getJSON(post.commentURL); //這裏手動返回一個Promise對象,後面then的回調函數funcA和funcB執行哪個,取決該返回的Promise的狀態
      }).then(function funcA(comments) {
        console.log("resolved: ", comments);
      }, function funcB(err){
        console.log("rejected: ", err);
      });
      //用箭頭函數寫則簡明不少:
      getJSON("/post/1.json").then(
        post => getJSON(post.commentURL)
      ).then(
        comments => console.log("resolved: ", comments),
        err => console.log("rejected: ", err)
      );

Promise.prototype.catch()

  • 返回Promise對象
  • Promise.prototype.catch方法是.then(null, rejection)的別名,用於指定異步操做發生錯誤時的回調函數。
    • 例子一:
    const promise = new Promise(function(resolve, reject) {
        throw new Error('err');//若是拋出錯誤是在resolve以後,catch就不會捕捉到錯誤,由於Promise 狀態已經變成resolved,再拋出錯誤是無效的
        resolve('test')
      }).then((value)=>{
          console.log(value)
      },(err)=>{
      console.log(err)
      });
      promise.catch(function(error) {
        console.log(error);
      });
    • 例子二:
    function timeout(ms) {
        return new Promise((resolve, reject) => {
          setTimeout(resolve, ms, 'done');
        });
      }
    
      timeout(2000).then((value) => {
        throw new Error('test1');
        console.log(value);
      },
      (value) => {
      throw new Error('test2');
        console.log(value+1);//不會執行
      }
      ).catch((err)=>{
      console.log(err+2); //test12
      });
    • 不要在then方法裏面定義 Reject 狀態的回調函數(即then的第二個參數),建議使用catch方法。
    // 很差的作法
      promise
        .then(function(data) {
          // success
        }, function(err) {
          // error
        });
    
      // 好的作法,這樣能夠捕捉前面的then內部拋出的錯誤
      promise
        .then(function(data) { //cb
          // success
        })
        .catch(function(err) {
          // error
        });

Promise.prototype.finally()

  • 無論promise最後的狀態,在執行完then或catch指定的回調函數之後,都會執行finally方法指定的回調函數

Promise.all()

  • Promise.all方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。
  • 本擴展實現了將多個異步操做合併爲一個操做,也就是並行處理異步,最後統一操做結果,注意:本方法只能經過Promise對象直接調用,實例不能進行此操做。 all()接收一個參數數組,數組中的每一項都對應一個

Promise.race()

  • Promise.race方法一樣是將多個 Promise 實例,包裝成一個新的 Promise 實例。
    const p = Promise.race([p1, p2, p3]);
  • 只要p一、p二、p3之中有一個實例率先改變狀態,p的狀態就跟着改變。那個率先改變的 Promise 實例的返回值,就傳遞給p的回調函數。
  • Promise.race方法的參數與Promise.all方法同樣,若是不是 Promise 實例,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理。

Promise.resolve

  • 將對象轉化成Promise對象
  • 參數:
    • 參數是一個Promise實例,則不作任何變化,直接返回該Promise實例
    • 參數是一個thenable對象,就是有then方法的對象,Promise.resolve方法會將這個對象轉爲 Promise 對象,而後就當即執行thenable對象的then方法。
      let thenable = {
        then: function(resolve, reject) {
          resolve(42);
        }
      };
      
      let p1 = Promise.resolve(thenable);
      p1.then(function(value) {
        console.log(value);  // 42
      });
    • 參數不是具備then方法的對象,或根本就不是對象,則Promise.resolve方法返回一個新的Promise對象,狀態爲resolve
    • 不傳參數,直接返回一個resolved狀態的 Promise對象
    //這樣能夠獲得一個Promise對象
    const p = Promise.resolve();
    
    p.then(function () {
      // ...
    });

Promise.reject()

  • 返回一個狀態爲rejected的Promise對象
  • 參數
    • 傳入的參數做爲後續then中reject狀態回調函數的參數
    • 具備then方法的對象,則後續的then的reject狀態回調參數函數接受的參數是該對象
      const thenable = {
        then(resolve, reject) {
          reject('出錯了');
        }
      };
      
      Promise.reject(thenable)
      .catch(e => {
        console.log(e === thenable) //這裏捕獲的是thenable對象,而不是‘出錯了’字符串,不像Promise.resolve會執行thenable對象的then方法
      })

Promise.try()

  • 同步的函數同步執行,異步函數異步執行
    const f = () => console.log('now');
    Promise.try(f);
    console.log('next');
    // now
    // next
相關文章
相關標籤/搜索