從基礎的層次來講,理解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非同步處理有所幫助。

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

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

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

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

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

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

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

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


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

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

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

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

Atom編輯器mac版下載
最受歡迎的的開源編輯器

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