以jQuery中$.Deferred物件為例講解promise物件是如何處理非同步問題_jquery
Promises是一種令程式碼異步行為更優雅的抽象,它很有可能是JavaScript的下一個程式設計範式,一個Promise即表示任務結果,無論該任務是否完成。
在一些現代瀏覽器中已經提供了原生的Promise對象,其遵循Promise/A 標準。在jQuery1.5 ,提供了$.Deferred(其可以被轉換為promise物件)。在許多知名的框架中,也提供了promise物件。 promise物件在javascript中已經是一種很重要的模式,它在解決非同步問題時所表現出的優雅,正是javascript所需要的。以下以jQuery中的$.Deferred物件為例,來看看promise物件是如何處理非同步問題。關於$.Deferred對象,可以到jQuery官網查看,這裡就不贅述了。
一、封裝非同步操作
首先,我們以載入圖片為例,看以下程式碼:
//加载图片函数 var loadImg = function(url){ var img = new Image() , deferred = $.Deferred() ; img.src = url ; img.onload = function(){ //成功则触发deferred.resolve deferred.resolve( this ) ; } ; img.onerror = function(e){ //失败则触发deferred.reject deferred.reject( e ); } ; //返回promise对象 return deferred.promise() ; } ; //请求图片 var request = loadImg('http://r2.ykimg.com/0515000054AFFC2D6737B343930AFAD6') ; //请求成功 request.done(function(img){ //code }) ; //可以注册多个回调,当请求成功时,会按注册的顺序执行,fail和always也有此性质 request.done(function(img){ // code }); //请求失败 request.fail(function(){ // code }) ; //请求完毕 request.always(function(){ //code });
以上的程式碼,我封裝了圖片載入的操作,將他們委託給$.Deferred,最後產生一個promise回傳。使用這樣的方式,相較於用對外暴露回調的方式,顯得更乾淨、更清晰。這麼做的另一個更重要的原因是,promise的連結。
二、promise的連接
我們還是以上面圖片載入的程式碼為例,來看看如何做promise的連接,看以下程式碼:
var request = loadImg('http://b1.hucdn.com/upload/item/1411/13/89613257775992_800x800.jpg') ; request.done(function(img){ //code }) ; //request连接别的promise之后返回的promise var request3 = request.then(function(img){ //request执行成功时 连接request1 var request1 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ; return request1 ; },function(e){ //request执行失败时 连接request2 var request2 = loadImg('http://b1.hucdn.com/upload/item/1410/19/29492535741725_800x800.jpg') ; return request2 ; }); //request执行并且request1或request2成功执行时 request3.done(function(done){ //code }) ;
promise物件提供了then的方法,它接受兩個回呼:onResolve和onReject,在回呼中返回promise,就可以完成promise之間的連接。透過這種方式,可以使非同步操作串列的執行。
同時,jQuery也提供了另一種連接方式,看程式碼:
var request = loadImg('http://b1.hucdn.com/upload/item/1412/23/48188827139381_800x800.jpg') ; var request1 = loadImg('http://b1.hucdn.com/upload/item/1412/06/50258594673502_800x800.jpg') ; //通过$.when连接promise var request2 = $.when(request,request1) ; request2.done(function(img,img){ //code }) ;
jQuery中提供了$.when這個函數,它可以接受n個promise物件為參數,它是將promise的執行結果連接在一起。使用這種方式,多個非同步操作可以並行執行。
三、The End
這裡的程式碼是以載入圖片為例,同樣的做法可以應用到其他的非同步操作中去。例如jQuery中的$.ajax、$.fn.animate,呼叫它們回傳的就是promise。在node端,也可以把一些非同步操作(讀取資料庫、讀取檔案等)封裝成promise。繼而對多個promise實現合併的操作,使其串列或並行執行。
附:deferred物件
deferred除了用來轉換promise物件外,本身也是個很有用的物件。它除了提供像promise物件的那些方法和屬性外,還有notify函數和progress函數,這兩個函數在實現進度條和瀑布流的時候,有很大的用處。
在實現進度條時,resolve和done函數可以用來定義進度條讀取到100%時的觸發時機和觸發邏輯,notify和progress函數可以用來定義進度條在讀取中的觸發時機和觸發邏輯。 reject和fail函數可以用來定義進度讀取失敗時的觸發時機和觸發邏輯。
在實現瀑布流時,resolve和done函數可以用來定義當資料已經全部載入到頁面的觸發時機和觸發邏輯,notify和progress函數可以用來定義瀑布流讀取下一頁的觸發時機和觸發邏輯。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

本文討論了在瀏覽器中優化JavaScript性能的策略,重點是減少執行時間並最大程度地減少對頁面負載速度的影響。

Python和JavaScript開發者的薪資沒有絕對的高低,具體取決於技能和行業需求。 1.Python在數據科學和機器學習領域可能薪資更高。 2.JavaScript在前端和全棧開發中需求大,薪資也可觀。 3.影響因素包括經驗、地理位置、公司規模和特定技能。

本文討論了使用瀏覽器開發人員工具的有效JavaScript調試,專注於設置斷點,使用控制台和分析性能。

本文說明瞭如何使用源地圖通過將其映射回原始代碼來調試JAVASCRIPT。它討論了啟用源地圖,設置斷點以及使用Chrome DevTools和WebPack之類的工具。

如何在JavaScript中將具有相同ID的數組元素合併到一個對像中?在處理數據時,我們常常會遇到需要將具有相同ID�...

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。
