Javascript中的異步編程規(guī)范Promises/A詳細(xì)介紹
Javascript里異步編程逐漸被大家接受,先前大家一般通過回調(diào)嵌套,setTimeout、setInterval等方式實(shí)現(xiàn),代碼看起來非常不直觀,不看整個代碼邏輯很難快速理解。Javascript里異步函數(shù)大概有I/O函數(shù)(Ajax、postMessage、img load、script load等)、計(jì)時函數(shù)(setTimeout、setInterval)等。
這些我們都很熟悉,在復(fù)雜的應(yīng)用中往往會嵌套多層,甚至以為某些步驟未完成而導(dǎo)致程序異常,最簡單的例子:比如你往DOM中注入節(jié)點(diǎn),你必須等待節(jié)點(diǎn)注入后在操作這個節(jié)點(diǎn),當(dāng)大量節(jié)點(diǎn)注入的時候,時間往往很難把握。如果我們得代碼依賴第三方api的數(shù)據(jù)。我們無法獲悉一個API響應(yīng)的延遲時間,應(yīng)用程序的其他部分可能會被阻塞,直到它返回結(jié)果。Promises對這個問題提供了一個更好的解決方案,它是非阻塞的,并且與代碼完全解耦 。
那么,我看看Javascript里異步編程,首先推薦大家看看相對來說比較流行的Promises/A規(guī)范。
Promises/A規(guī)范
注:為了便于理解,描述可能和Promises/A規(guī)范有所出入;
CommonJS之Promises/A規(guī)范,通過規(guī)范API接口來簡化異步編程,使我們的異步邏輯代碼更易理解。
遵循Promises/A規(guī)范的實(shí)現(xiàn)我們稱之為Promise對象,Promise對象有且僅有三種狀態(tài):unfulfilled(未完成)、fulfilled(已完成)、failed(失敗/拒絕);初始創(chuàng)建的時候是unfulfilled(未完成)狀態(tài),狀態(tài)只可以從unfulfilled(未完成)變成fulfilled(已完成),或者unfulfilled(未完成)變成failed(失敗/拒絕)。狀態(tài)一旦變成fulfilled(已完成)或者failed(失敗/拒絕),狀態(tài)就不能再變了。
Promises/A規(guī)范提供了一個在程序中描述延時(或?qū)恚└拍畹慕鉀Q方案。主要的思想不是執(zhí)行一個方法然后阻塞應(yīng)用程序等待結(jié)果返回后再回調(diào)其他方法,而是返回一個Promise對象來滿足未來監(jiān)聽。fulfilled狀態(tài)和failed狀態(tài)都可以被監(jiān)聽。Promise通過實(shí)現(xiàn)一個then接口來返回Promise對象來注冊回調(diào):
then接口用于監(jiān)聽一個Promise的不同狀態(tài)。fulfilledHandler用于監(jiān)聽fulfilled(已完成)狀態(tài),errorHandler用于監(jiān)聽failed(失敗/拒絕)狀態(tài),progressHandler用于監(jiān)聽unfulfilled(未完成)狀態(tài)。Promise不強(qiáng)制實(shí)現(xiàn)unfulfilled(未完成)的事件監(jiān)聽(例如我們知道舊版本的jQuery(1.5,1.6)的Deferred就是一個Promise的實(shí)現(xiàn),但沒有實(shí)現(xiàn)對unfulfilled(未完成)狀態(tài)的監(jiān)聽來回調(diào)progressHandler)。
一般認(rèn)為,then接口返回的是一個新的Promise對象,而不是原來的Promise對象,這個新的新的Promise對象可以理解為是原來Promise對象的一個視圖,它只包含原有Promise對象的一組方法,這些方法只能觀察原有Promise對象的狀態(tài),而無法更改deferred對象的內(nèi)在狀態(tài)。這樣可以避免多個調(diào)用者之間的沖突,多個調(diào)用者可以通過改變新的Promise對象狀態(tài)而不影響別的調(diào)用者。
另外,Promise提供了resolve(實(shí)現(xiàn)狀態(tài)由未完成到已完成)和reject(實(shí)現(xiàn)狀態(tài)由未完成到拒絕或失?。﹥蓚€接口實(shí)現(xiàn)狀態(tài)的轉(zhuǎn)變。
發(fā)一張圖片幫助理解一下:
有了Promise,就可以以同步的思維去編寫異步的邏輯了。在異步函數(shù)里,不能使用try/catch捕獲異常,也不能拋出異常。有了Promise,我們可以直接顯式定義errorHandler,相當(dāng)于捕獲異常。
以下是幾個遵循Promises/A規(guī)范的類庫,when,q,rsvp.js,jQuery.Deferred等等。
相關(guān)文章
jquery實(shí)現(xiàn)動態(tài)改變div寬度和高度
這篇文章主要介紹了jquery實(shí)現(xiàn)動態(tài)改變div寬度和高度,效果非常不錯,而且兼容性也很好,有需要的小伙伴可以參考下。2015-05-05jquery實(shí)現(xiàn)根據(jù)瀏覽器窗口大小自動縮放圖片的方法
這篇文章主要介紹了jquery實(shí)現(xiàn)根據(jù)瀏覽器窗口大小自動縮放圖片的方法,涉及jquery操作頁面元素屬性與樣式的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-07-07用jquery實(shí)現(xiàn)的一個超級簡單的下拉菜單
這篇文章主要介紹了用jquery實(shí)現(xiàn)的一個超級簡單的下拉菜單,需要的朋友可以參考下2014-05-05jquery 獲取自定義屬性(attr和prop)的實(shí)現(xiàn)代碼
jquery中用attr()方法來獲取和設(shè)置元素屬性,attr是attribute(屬性)的縮寫,在jQuery DOM操作中會經(jīng)常用到attr(),attr()有4個表達(dá)式2012-06-06jQuery使用bind函數(shù)實(shí)現(xiàn)綁定多個事件的方法
這篇文章主要介紹了jQuery使用bind函數(shù)實(shí)現(xiàn)綁定多個事件的方法,結(jié)合簡單實(shí)例形式分析了jQuery使用bind函數(shù)進(jìn)行多個事件綁定的操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-10-10