搜尋
首頁web前端js教程javascript非同步處理工作機制詳解_javascript技巧

從基礎的層次來講,理解JavaScript的定時器是如何運作的是非常重要的。計時器的執行常常和我們的直覺想像不同,那是因為JavaScript引擎是單執行緒的。我們先來認識一下下面三個函數是如何控制計時器的。

var id = setTimeout(fn, delay); - 初始化一個計時器,然後在指定的時間間隔後執行。該函數傳回一個唯一的標誌ID(Number類型),我們可以使用它來取消計時器。
var id = setInterval(fn, delay); - 和setTimeout有些類似,但它是連續呼叫一個函數(時間間隔是delay參數)直到它被取消。
clearInterval(id);, clearTimeout(id); - 使用計時器ID(setTimeout 和 setInterval的回傳值)來取消計時器回呼的發生
為了理解計時器的內在執行原理,有一個重要的概念需要加以探討:計時器的延遲(delay)是無法得到保障的。由於所有JavaScript程式碼都是在一個執行緒執行的,因此所有非同步事件(例如,滑鼠點擊和計時器)只有在擁有執行機會時才會執行。

在這個圖表中有許多資訊需要理解,如果完全理解了它們,你會對JavaScript引擎如何實現非同步事件有一個很好的認識。這是一個一維的圖示:垂 直方向表示時間,藍色的區塊表示JavaScript程式碼執行區塊。例如第一個JavaScript程式碼執行區塊需要大約18ms,滑鼠點擊所觸發的程式碼執行 區塊需要11ms,等等。

由於JavaScript引擎相同時間只執行一條程式碼(這是由於JavaScript單執行緒的性質),所以每個JavaScript程式碼執行區塊會 「阻塞」其它非同步事件的執行。這意味著當一個非同步事件發生(例如,滑鼠點擊,計時器被觸發,或Ajax非同步請求)後,這些事件的回呼函數將排在執行佇列的最後等待執行(實際上,排隊的方式根據瀏覽器的不同而不同,所以這裡只是一個簡化);

從第一個JavaScript執行區塊開始研究,在第一個執行區塊中兩個計時器被初始化:一個10ms的setTimeout()和一個10ms的setInterval()。 依據何時何地計時器被初始化(計時器初始化完畢後就會開始計時),計時器實際上會在第一個程式碼區塊執行完畢前被觸發。但是,計時器上綁定的函數不會立即執行 (不被立即執行的原因是JavaScript是單線程的)。實際上,被延遲的函數將依序排在執行佇列的最後,等待下一次恰當的時間再執行。

此外,在第一個JavaScript執行區塊中我們看到了一個「滑鼠點擊」事件發生了。一個JavaScript回呼函數綁定在這個非同步事件上了(我們從來不知道用戶什麼時候執行這個(點擊)事件,因此認為它是異步的),這個函數不會立即執行,就像上面的計時器一樣,它將排在執行佇列的最後,等待下一次恰當的時候執行。

當第一個JavaScript執行區塊執行完畢後,瀏覽器會立即問一個問題:哪個函數(語句)在等待執行?在這時,一個「滑鼠點擊事件處理函數」和 一個「計時器回呼函數」都在等待執行。瀏覽器會選擇一個(實際上選擇了“滑鼠點擊事件的處理函數”,因為由圖可知它是先進隊的)立即執行。而「計時器回呼 函數」將等待下次適合的時間執行。

注意,當「滑鼠點選事件處理函數」執行的時候,setInterval的回呼函數第一次就被觸發了。和setTimeout的回呼函數一樣,它將排到執行佇列的最後等待執行。但是,請務必注意這一點:當setInterval回呼函數第二次觸發時(此時setTimeout函數仍在執行)setInterval的第一次觸發將被拋棄掉。當一個很長的程式碼區塊在執行時,可能會把所有的setInterval回呼函數都排在執行佇列的後面,程式碼區塊執行完之後,結果就會是一大串的setInterval回呼函數等待執行,並且這些函數之間沒有間隔,直到全部完成。所以,瀏覽器傾向於的當沒有更多interval的處理函數在排隊時再將下一個處理函數排到隊尾(這是由於間隔的問題)。

我們能夠發現,當第三個setInterval回呼函數被觸發時,先前的setInterval回呼函數仍在執行。這就說明了一個很重要的事實:setInterval不會考慮目前正在執行什麼,而把所有的阻塞的函數排到佇列尾部。這意味著兩次setInterval回呼函數之間的時間間隔會被犧牲掉(縮減)。

最後,當第二個setInterval回呼函數執行完畢後,我們可以看到沒有任何程式等待JavaScript引擎執行了。這就意味著瀏覽器現在正在等待一個新的非同步事件的發生。在50ms時一個新的setInterval回呼函數又被觸發,這時,沒有任何的執行塊阻塞它的執行了。所以它會立刻被執行。

讓我們用一個例子來闡明setTimeout和setInterval之間的區別:

 setTimeout ( function ( ) { 
   /* Some long block of code... */ 
  setTimeout (arguments. callee, 10 ); 
  }, 10 ); 
  
 setInterval ( function ( ) { 
   /* Some long block of code... */ 
  }, 10 );
 

這兩句程式碼乍看之下沒什麼差別,但是它們是不同的。 setTimeout回呼函數的執行和上一次執行之間的間隔至少有10ms(可能會更多,但不會少於10ms),而setInterval的回呼函數將嘗試每隔10ms執行一次,無論上次是否執行完畢。

在這裡我們學到了很多知識,總結一下:

JavaScript引擎是單執行緒的,強制所有的非同步事件排隊等待執行
setTimeout 和 setInterval 在執行非同步程式碼的時候有著根本的不同
如果計時器被阻塞而無法立即執行,它將延遲執行直到下一次可能執行的時間點才被執行(比期望的時間間隔要長些)
如果setInterval回呼函數的執行時間將足夠長(比指定的時間間隔長),它們將連續執行並且彼此之間沒有時間間隔。

以上所述就是本文的全部內容了,希望能夠對大家學習javascript非同步處理有所幫助。

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境