快速將 Promise 運用在開發中

這篇文章面向對Promise不甚瞭解的朋友,我將告訴你如何把它快速運用在開發中。javascript

什麼是Promise?

簡單幾句介紹一下。Promise是抽象異步處理對象以及對其進行各類操做的組件。你能夠理解爲:它的出現,是爲了讓咱們更方便的進行異步處理。java

在Promise出現以前,說到JavaScript的異步處理,咱們都會想到回調函數,like this:promise

getAsync("fileA.txt", function(error, result){
  if(error){// 取得失敗時的處理 throw error;
    throw error;
  }
});複製代碼

上面遵循Node.js的規定,回調的第一個參數是error。若是全部的回調函數都像Node.js同樣,統一參數使用規則的話,那寫法會很明瞭,但也僅僅是編碼規範而已,使用不一樣的寫法也不會出錯。微信

而Promise則是把異步處理對象和處理規則進行規範化,並採用統一的接口來編寫,使用規定方法以外的寫法都會出錯。異步

咱們能夠先看一個簡單的使用Promise進行異步處理的例子:async

var promise = getAsyncPromise("fileA.txt");

promise.then(function(result){
  // 獲取文件內容成功時的處理
}).catch(function(error){
  // 獲取文件內容失敗時的處理
});複製代碼

看上去和回調函數有些不同,在使用Promise進行異步處理的時候,咱們必須按照接口規定的方法編寫處理代碼。函數

也便是說,除了使用Promise規定的方法(上面的thencatch),其餘的方法都是不能使用的,而回調函數能夠自定義回調的參數。學習

因此,Promise能夠將複雜的異步處理輕鬆的進行模式化,沒有理由讓你不使用它。ui

接下來,咱們看看怎麼把Promise運用到開發中,這個纔是你們想了解的。this

學習Promise

在運用到開發以前,咱們有必要先學習一些Promise的基本API(暫時看的有點糊塗不要緊,等會的例子實踐會和你們講清楚的)。

目前大體有下面三種類型:

1.Constructor(構造器)

咱們從構造函數Promise來建立一個新promise對象做爲接口。

要建立一個promise對象,可使用new來調用Promise構造器來進行實例化。

var promise = new Promise(function(resolve, reject) { // 異步處理
  // 處理結束後、調用resolve 或 reject
});複製代碼

2.Instance Method(實例方法)

在經過new生成的promise對象時,咱們設置了在resolve(成功)和reject(失敗)時調用的回調函數,咱們可使用promise.then()實例方法。

promise.then(onFulfilled,onReject);複製代碼
  • resolve(成功)時:onFulfilled會被調用

  • reject(失敗)時:onReject會被調用

onFulfilledonReject都爲可選參數

promise.then成功和失敗時均可以使用,另外在異常處理時,可使用promise.then(undefined, onReject)這種方式,只指定reject時的回調函數便可。不過這種狀況下,使用promise.catch()是個明智之選。

promise.catch(onReject);複製代碼

3.Static Method(靜態方法)

promise.all()Promise.resolve()等在內,主要都是一些輔助方法(能夠理解爲一些語法糖),這裏不做深刻探討。

運用在開發中

咱們先來看一段Promise使用流程代碼:

function asyncFunction() {  //(1)
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('Async Hello World');
    }, 300);
  });
}

asyncFunction().then(function(value) {  //(2)
  console.log(value); //300ms後打印 "Async Hello World"
}).catch(function(error) {  //(3)
  console.log(error);
})複製代碼

分析一下上面代碼。

執行(1)處函數,會返回一個Promise對象,Promise對象內部在300ms後執行resolve()方法,這個方法調用(2)處的then()方法,並傳入參數,若是Promise對象內部出現任何錯誤(好比平臺不支持setTimeout方法),就會執行(3)處的catch()發放,並把錯誤做爲參數傳入。

這裏提一下,我看到不少朋友把Promise理解爲Ajax的一種擴展,其實並非這樣的,Ajax只是一種請求數據的方式,由於Ajax是異步的,因此咱們能夠用Promise去管理Ajax請求,但這並不意味這Promise只服務於Ajax,只要是異步處理,咱們均可以使用Promise去處理,就好比上面的setTimeout

看到這裏你們對Promise應該有一個大概的認識了,實際開發中Promise大部分時間仍是搭配Ajax使用,咱們來看看應該怎麼作,下面用原生的方式請求Ajax,你們也溫習一下:

function getURL(URL) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();

    req.open('GET', URL, true);

    req.onload = function() {
      if (req.status === 200) {
        resolve(req.responseText);
      }else {
        reject(new Error(req.statusText));
      }
    };

    req.onerror = function() {
      reject.(new Error(req.statusText));
    };

    req.send();
  });
}

// 運行示例
var URL = "https://rockjins.js.org";
getURL(URL).then(function onFulfilled(value){
  console.log(value);
}).catch(function onRejected(error){
  console.error(error);
});複製代碼

getURL只有在XHR取得狀態爲200時纔會調用resolve,也就是數據取得成功時,而其餘狀況(數據取得失敗)則會調用reject

當調用resolve(req.responseText)時,then方法也會被調用,並接收到req.responseText參數。

熟悉Node.js的朋友在寫回調時會會將callback(error,response)的第一個參數設爲error對象,在Promise中,resolve(成功)/reject(失敗)擔當了這個職責。

XHR中onerror觸發時,就是發生錯誤時,理所固然要調用reject,咱們重點來看下傳給reject的值。

發生錯誤時要像這樣reject(new Error(req.statusText)),建立一個Error對象再講具體的值傳入進去。傳給reject的值也沒有什麼特殊限制,通常只要是Error對象(或繼承自Error對象)便可。

小結

其實你理解了Promise的運做流程,使用它十分方便和簡單,它就是一個異步管理器,幫助咱們更好地去進行異步處理。

試想,若是Promise真的很複雜,那它出現的意義是什麼?本末倒置了,哈哈。

喜歡本文的朋友能夠關注個人微信公衆號,不按期推送一些好文。

本文出自Rockjins Blog,轉載請與做者聯繫。不然將追究法律責任。

相關文章
相關標籤/搜索