首頁 web前端 js教程 Javascript非同步程式設計的4種方法讓你寫出更優秀的程式_javascript技巧

Javascript非同步程式設計的4種方法讓你寫出更優秀的程式_javascript技巧

May 16, 2016 pm 05:43 PM
非同步程式設計

你可能知道,Javascript語言的執行環境是"單執行緒"(single thread)。
所謂"單線程",就是指一次只能完成一件任務。如果有多個任務,就必須排隊,前面一個任務完成,再執行後面一個任務,以此類推。
Javascript非同步程式設計的4種方法讓你寫出更優秀的程式_javascript技巧 
這種模式的好處是實現起來比較簡單,執行環境相對單純;壞處是只要有一個任務耗時很長,後面的任務都必須排隊等著,會拖延整個程序的執行。常見的瀏覽器無回應(假死),往往是因為某一段Javascript程式碼長時間運作(例如死循環),導致整個頁面卡在這個地方,其他任務無法執行。

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

"同步模式"就是上一段的模式,後一個任務等待前一個任務結束,然後再執行,程式的執行順序與任務的排列順序是一致的、同步的;"非同步模式"則完全不同,每一個任務有一個或多個回調函數(callback),前一個任務結束後,不是執行後一個任務,而是執行回調函數,後一個任務則是不等前一個任務結束就執行,所以程序的執行順序與任務的排列順序是不一致的、非同步的。
Javascript非同步程式設計的4種方法讓你寫出更優秀的程式_javascript技巧 
"非同步模式"非常重要。在瀏覽器端,耗時很長的操作都應該非同步執行,避免瀏覽器失去回應,最好的例子就是Ajax操作。在伺服器端,"非同步模式"甚至是唯一的模式,因為執行環境是單線程的,如果允許同步執行所有http請求,伺服器效能會急劇下降,很快就會失去回應。

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

一、回呼函數
這是非同步程式設計最基本的方法。
假定有兩個函數f1和f2,後者等待前者的執行結果。

複製程式碼 程式碼如下:

f1();  🎜>

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


複製程式碼 程式碼如下:
function f. () {
      // f1的任務代碼
      callback();
     callback();
    }, 1000);程式碼變成下面這樣:



複製程式碼

程式碼如下: f1(f2); f1(f2);
採用這種方式,我們把同步操作變成了非同步操作,f1不會堵塞程式運行,相當於先執行程式的主要邏輯,將耗時的操作推遲執行。
回呼函數的優點是簡單、容易理解和部署,缺點是不利於程式碼的閱讀和維護,各個部分之間高度耦合(Coupling),流程會很混亂,而且每個任務只能指定一個回調函數。


二、事件監聽

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


複製程式碼 程式碼如下: f1.on('done', f22); 🎜>
上面這行程式碼的意思是,當f1發生done事件,就執行f2。然後,對f1進行改寫:



複製程式碼
程式碼如下: function f1()     setTimeout(function () {
      // f1的任務代碼
    
  }


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")的意思是,f1執行完成後,向"訊號中心"jQuery發布"done"訊號,從而引發f2的執行。
此外,f2完成執行後,也可以取消訂閱(unsubscribe)。 程式碼如下:


jQuery.unsubscribe(">

jQuery.unsubscribe("done", f2); 🎜>

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

Promises物件是CommonJS工作小組提出的一種規範,目的是為非同步程式提供統一介面。
簡單說,它的思想是,每一個非同步任務返回一個Promise對象,該對像有一個then方法,允許指定回調函數。例如,f1的回呼函數f2,可以寫成: 複製程式碼
程式碼如下:


程式碼如下:
程式碼如下: f1要進行如下改寫(這裡使用的是jQuery的實作):


複製程式碼


程式碼如下:


function f1(){
    var dfd = $.Deferred();       dfd.resolve();
    }, 500);
     }, 500);
     return df.proise>; 🎜>這樣寫的優點在於,回調函數變成了鍊式寫法,程式的流程可以看得很清楚,而且有一整套的配套方法,可以實現許多強大的功能。
比如,指定多個回調函數: 複製代碼
代碼如下:

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

再比如,指定發生錯誤時的回呼函數: 複製程式碼
程式碼如下:

f1().then(f2).fail(f3);
而且,它還有一個前面三種方法都沒有的好處:如果一個任務已經完成,再增加回呼函數,則回呼函數會立即執行。所以,你不用擔心是否錯過了某個事件或訊號。這種方法的缺點就是要寫和理解,都相對比較難。
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

熱門話題

Java教學
1664
14
CakePHP 教程
1422
52
Laravel 教程
1316
25
PHP教程
1266
29
C# 教程
1239
24
如何用 C++ 函數實作非同步程式設計? 如何用 C++ 函數實作非同步程式設計? Apr 27, 2024 pm 09:09 PM

摘要:C++中的非同步程式設計允許多工處理,無需等待耗時操作。使用函數指標建立指向函數的指標。回調函數在非同步操作完成時被呼叫。 boost::asio等函式庫提供非同步程式支援。實戰案例示範如何使用函數指標和boost::asio實現非同步網路請求。

PHP中如何使用ReactPHP進行非同步編程 PHP中如何使用ReactPHP進行非同步編程 Jun 27, 2023 am 09:14 AM

隨著Web應用程式變得越來越複雜,程式設計師不得不採用非同步程式來處理大量請求和I/O操作。 PHP:HypertextPreprocessor也不例外。為了滿足這項需求,ReactPHP已成為目前最受歡迎的PHP非同步程式設計框架之一。在本文中,將討論如何在PHP中使用ReactPHP進行非同步程式設計。 1.ReactPHP簡介ReactPHP是基於事件驅動編程

JavaScript函數非同步程式設計:處理複雜任務的必備技巧 JavaScript函數非同步程式設計:處理複雜任務的必備技巧 Nov 18, 2023 am 10:06 AM

JavaScript函數非同步程式設計:處理複雜任務的必備技巧引言:在現代前端開發中,處理複雜任務已經成為了必不可少的一部分。而JavaScript函數非同步程式設計技巧則是解決這些複雜任務的關鍵。本文將介紹JavaScript函數非同步程式設計的基本概念和常用的實作方法,並提供具體的程式碼範例,幫助讀者更好地理解和使用這些技巧。一、非同步程式設計的基本概念在傳統的同步程式設計中,程式碼按

Java框架非同步程式設計中常見的問題與解決方案 Java框架非同步程式設計中常見的問題與解決方案 Jun 04, 2024 pm 05:09 PM

Java框架非同步程式設計中常見的3個問題和解決方案:回呼地獄:使用Promise或CompletableFuture以更直覺的風格管理回呼。資源競爭:使用同步原語(如鎖)保護共享資源,並考慮使用執行緒安全性集合(如ConcurrentHashMap)。未處理異常:明確處理任務中的異常,並使用異常處理框架(如CompletableFuture.exceptionally())處理異常。

深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? 深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? Sep 11, 2023 pm 01:52 PM

深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? PHP8是PHP程式語言的最新主要版本,帶來了許多令人興奮的新功能和改進。其中最突出的特性之一是對非同步程式設計的支援。非同步程式設計可讓我們在處理並發任務時提高效能和回應能力。本文將深入探討PHP8的非同步程式設計特性,並介紹如何有效率地使用它們。首先,讓我們來了解一下什麼是非同步程式設計。在傳統的同步程式設計模型中,程式碼依照線性的順

golang框架如何處理並發和非同步程式設計? golang框架如何處理並發和非同步程式設計? Jun 02, 2024 pm 07:49 PM

Go框架利用Go的並發和非同步特性提供高效處理並發和非同步任務的機制:1.透過Goroutine實現並發,允許同時執行多個任務;2.透過通道實現非同步編程,在不阻塞主執行緒的情況下執行任務;3.適用於實戰場景,如並發處理HTTP請求、非同步取得資料庫資料等。

如何在PHP中實現非同步訊息處理 如何在PHP中實現非同步訊息處理 Jul 10, 2023 am 08:19 AM

如何在PHP中實現非同步訊息處理引言:在現代的Web應用程式中,非同步訊息處理變得越來越重要。非同步訊息處理可以提高系統的效能和可擴展性,並改善使用者體驗。 PHP作為一種常用的伺服器端程式語言,也可以透過一些技術來實現非同步訊息處理。在本文中,我們將介紹一些PHP中實作非同步訊息處理的方法,並提供程式碼範例。使用訊息佇列訊息佇列是一種解耦系統元件的方式,它允許不同的元件在

Python非同步程式設計: 實現高效並發的非同步程式碼之道 Python非同步程式設計: 實現高效並發的非同步程式碼之道 Feb 26, 2024 am 10:00 AM

1.為什麼要使用非同步程式設計?傳統程式設計使用阻塞式I/O,這表示程式會等待某個操作完成,然後才能繼續執行。這對於處理單一任務可能很有效,但對於處理大量任務時,可能會導致程式變慢。非同步程式設計則打破了傳統阻塞式I/O的限制,它使用非阻塞式I/O,這意味著程式可以將任務分發到不同的執行緒或事件循環中執行,而無需等待任務完成。這允許程式同時處理多個任務,提高程式的效能和效率。 2.python非同步程式設計的基礎Python非同步程式設計的基礎是協程和事件循環。協程是允許函數在暫停和恢復之間切換的函數。事件循環則負責調度

See all articles