搜尋
首頁web前端js教程Javascript非同步程式設計的4種方法介紹

Javascript非同步程式設計的4種方法介紹

Oct 02, 2017 pm 12:13 PM
javascriptjs介紹

你可能知道,Javascript語言的執行環境是」單執行緒」(single thread)。

所謂”單線程”,就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。

這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是只要有一個任務耗時很長,後面的任務都必須排隊等著,會拖延整個程式的執行。常見的瀏覽器無回應(假死),往往是因為某一段Javascript程式碼長時間運行(例如死循環),導致整個頁面卡在這個地方,其他任務無法執行。

為了解決這個問題,Javascript語言將任務的執行模式分成兩種:同步(Synchronous)和非同步(Asynchronous)。

「同步模式」就是上一段的模式,後一個任務等待前一個任務結束,然後再執行,程式的執行順序與任務的排列順序是一致的、同步的;」非同步模式」則完全不同,每一個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、非同步的。

「非同步模式」非常重要。在瀏覽器端,耗時很長的操作都應該非同步執行,避免瀏覽器失去回應,最好的例子就是Ajax操作。在伺服器端,」非同步模式」甚至是唯一的模式,因為執行環境是單線程的,如果允許同步執行所有http請求,伺服器效能會急劇下降,很快就會失去回應。

本文總結了」非同步模式」程式設計的4種方法,理解它們可以讓你寫出結構更合理、效能更出色、維護更方便的Javascript程式。

一、回呼函數

這是非同步程式設計最基本的方法。

假定有兩個函數f1和f2,後者等待前者的執行結果。

f1();f2();

如果f1是一個很耗時的任務,可以考慮改寫f1,把f2寫成f1的回呼函數。

function f1(callback){   
    setTimeout(function () {      // f1的任务代码      
    callback();
    }, 1000);
  }

執行程式碼就變成下面這樣:

  f1(f2);

採用這種方式,我們把同步操作變成了非同步操作,f1不會堵塞程式運行,相當於先執行程式的主要邏輯,將耗時的操作延遲執行。

回呼函數的優點是簡單、容易理解和部署,缺點是不利於程式碼的閱讀和維護,各個部分之間高度耦合(Coupling),流程會很混亂,而且每個任務只能指定一個回調函數。

二、事件監聽

另一個想法是採用事件驅動模式。任務的執行不取決於程式碼的順序,而取決於某個事件是否發生。
還是以f1和f2為例。首先,為f1綁定一個事件(這裡採用的jQuery的寫法)。

f1.on('done', f2);

上面這行程式碼的意思是,當f1發生done事件,就執行f2。然後,對f1進行改寫:

 function f1(){    
     setTimeout(function () {      // f1的任务代码      
     f1.trigger('done');
    }, 1000);
  }

f1.trigger(‘done’)表示,執行完成後,立即觸發done事件,從而開始執行f2。
這種方法的優點是比較容易理解,可以綁定多個事件,每個事件可以指定多個回調函數,而且可以」去耦合」(Decoupling),有利於實現模組化。缺點是整個程式都要變成事件驅動型,運作流程會變得很不清晰。

三、發布/訂閱

上一節的”事件”,完全可以理解成”信號”。

我們假定,存在一個”信號中心”,某個任務執行完成,就向信號中心”發布”(publish)一個信號,其他任務可以向信號中心”訂閱”(subscribe)這個信號,從而知道什麼時候自己可以開始執行。這就叫做」發布/訂閱式」(publish-subscribe pattern),又稱」觀察者模式」(observer pattern)。

這個模式有多種實現,以下採用的是Ben Alman的Tiny Pub/Sub,這是jQuery的一個外掛。

首先,f2向”訊號中心”jQuery訂閱”done”訊號。

 jQuery.subscribe("done", f2);

然後,f1進行如下改寫:

  function f1(){    
      setTimeout(function () {      // f1的任务代码      
      jQuery.publish("done");
    }, 1000);
  }

jQuery.publish(“done”)的意思是,f1執行完成後,向”信號中心”jQuery發布”done 」信號,從而引發f2的執行。

此外,f2完成執行後,也可以取消訂閱(unsubscribe)。

 jQuery.unsubscribe("done", f2);

這種方法的性質與」事件監聽」類似,但是明顯優於後者。因為我們可以透過查看”訊息中心”,了解存在多少訊號、每個訊號有多少訂閱者,從而監控程式的運作。

四、Promises物件

Promises物件是CommonJS工作小組提出的規範,目的是為非同步程式設計提供統一介面。

簡單說,它的想法是,每一個非同步任務返回一個Promise對象,該物件有一個then方法,允許指定回調函數。例如,f1的回呼函數f2,可以寫成:

f1().then(f2);

f1要进行如下改写(这里使用的是jQuery的实现):

  function f1(){    
      var dfd = $.Deferred();
    setTimeout(function () {      // f1的任务代码      
    dfd.resolve();
    }, 500);
    return dfd.promise;
  }

这样写的优点在于,回调函数变成了链式写法,程序的流程可以看得很清楚,而且有一整套的配套方法,可以实现许多强大的功能。

比如,指定多个回调函数:

f1().then(f2).then(f3);

再比如,指定发生错误时的回调函数:

 f1().then(f2).fail(f3);

而且,它还有一个前面三种方法都没有的好处:如果一个任务已经完成,再添加回调函数,该回调函数会立即执行。所以,你不用担心是否错过了某个事件或信号。这种方法的缺点就是编写和理解,都相对比较难。

你可能知道,Javascript语言的执行环境是”单线程”(single thread)。

所谓”单线程”,就是指一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。

这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行。常见的浏览器无响应(假死),往往就是因为某一段Javascript代码长时间运行(比如死循环),导致整个页面卡在这个地方,其他任务无法执行。

为了解决这个问题,Javascript语言将任务的执行模式分成两种:同步(Synchronous)和异步(Asynchronous)。

“同步模式”就是上一段的模式,后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的;”异步模式”则完全不同,每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。

“异步模式”非常重要。在浏览器端,耗时很长的操作都应该异步执行,避免浏览器失去响应,最好的例子就是Ajax操作。在服务器端,”异步模式”甚至是唯一的模式,因为执行环境是单线程的,如果允许同步执行所有http请求,服务器性能会急剧下降,很快就会失去响应。

以上是Javascript非同步程式設計的4種方法介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript的起源:探索其實施語言JavaScript的起源:探索其實施語言Apr 29, 2025 am 12:51 AM

JavaScript起源於1995年,由布蘭登·艾克創造,實現語言為C語言。 1.C語言為JavaScript提供了高性能和系統級編程能力。 2.JavaScript的內存管理和性能優化依賴於C語言。 3.C語言的跨平台特性幫助JavaScript在不同操作系統上高效運行。

幕後:什麼語言能力JavaScript?幕後:什麼語言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在瀏覽器和Node.js環境中運行,依賴JavaScript引擎解析和執行代碼。 1)解析階段生成抽象語法樹(AST);2)編譯階段將AST轉換為字節碼或機器碼;3)執行階段執行編譯後的代碼。

Python和JavaScript的未來:趨勢和預測Python和JavaScript的未來:趨勢和預測Apr 27, 2025 am 12:21 AM

Python和JavaScript的未來趨勢包括:1.Python將鞏固在科學計算和AI領域的地位,2.JavaScript將推動Web技術發展,3.跨平台開發將成為熱門,4.性能優化將是重點。兩者都將繼續在各自領域擴展應用場景,並在性能上有更多突破。

Python vs. JavaScript:開發環境和工具Python vs. JavaScript:開發環境和工具Apr 26, 2025 am 12:09 AM

Python和JavaScript在開發環境上的選擇都很重要。 1)Python的開發環境包括PyCharm、JupyterNotebook和Anaconda,適合數據科學和快速原型開發。 2)JavaScript的開發環境包括Node.js、VSCode和Webpack,適用於前端和後端開發。根據項目需求選擇合適的工具可以提高開發效率和項目成功率。

JavaScript是用C編寫的嗎?檢查證據JavaScript是用C編寫的嗎?檢查證據Apr 25, 2025 am 12:15 AM

是的,JavaScript的引擎核心是用C語言編寫的。 1)C語言提供了高效性能和底層控制,適合JavaScript引擎的開發。 2)以V8引擎為例,其核心用C 編寫,結合了C的效率和麵向對象特性。 3)JavaScript引擎的工作原理包括解析、編譯和執行,C語言在這些過程中發揮關鍵作用。

JavaScript的角色:使網絡交互和動態JavaScript的角色:使網絡交互和動態Apr 24, 2025 am 12:12 AM

JavaScript是現代網站的核心,因為它增強了網頁的交互性和動態性。 1)它允許在不刷新頁面的情況下改變內容,2)通過DOMAPI操作網頁,3)支持複雜的交互效果如動畫和拖放,4)優化性能和最佳實踐提高用戶體驗。

C和JavaScript:連接解釋C和JavaScript:連接解釋Apr 23, 2025 am 12:07 AM

C 和JavaScript通過WebAssembly實現互操作性。 1)C 代碼編譯成WebAssembly模塊,引入到JavaScript環境中,增強計算能力。 2)在遊戲開發中,C 處理物理引擎和圖形渲染,JavaScript負責遊戲邏輯和用戶界面。

從網站到應用程序:JavaScript的不同應用從網站到應用程序:JavaScript的不同應用Apr 22, 2025 am 12:02 AM

JavaScript在網站、移動應用、桌面應用和服務器端編程中均有廣泛應用。 1)在網站開發中,JavaScript與HTML、CSS一起操作DOM,實現動態效果,並支持如jQuery、React等框架。 2)通過ReactNative和Ionic,JavaScript用於開發跨平台移動應用。 3)Electron框架使JavaScript能構建桌面應用。 4)Node.js讓JavaScript在服務器端運行,支持高並發請求。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。