摘要:所以其實和所謂的異步調用事實上是通過將代碼段插入到代碼的執行隊列中實現的。當執行和的時候,會根據你設定的時間準確地找到代碼的插入點。綜上所述,其實終歸是單線程產物。無論如何異步都不可能突破單線程這個障礙。
發表過一片博客《跟著我用JavaScript寫計時器》,比較基礎.....有網友說應該寫一下setTimeout的原理和機制,嗯,今天就來寫一下吧:
直奔主題:setTimeout和setInterval是如何工作的呢?我們知道,js是單線程執行的(單線程j就是說在程序執行時,所走的程序路徑按照連續順序排下來,前面的必須處理好,后面的才會執行)。所以其實setTimeout和setInterval所謂的“異步調用”事實上是通過將代碼段插入到代碼的執行隊列中實現的。
而如何計算插入的時間點呢?自然是要用到我們所說的timer,也就是計時器。當執行setTimeout和setInterval的時候,timer會根據你設定的時間“準確”地找到代碼的插入點。當隊列“正常”地執行到插入點時,就觸發timer callback,也就是我們設定的回調函數:
function fn() { /* here is some codes */ alert("javascript"); setTimeout(function() {alert("ok!")},1000); } onload=fn;
上面這個例子就是我們通常的用法,應該容易理解。可是,timer真的能那么準確么?代碼隊列的執行真的能那么正常么?
還記得嗎?重新認識所謂的“異步”剛剛已經知道,事實上setTimeout和setInterval只是簡簡單單地通過插入代碼到代碼隊列來實現代碼的延遲執行(或者說異步執行)。但是事實上所謂的異步只是一個假象——它同樣運行在一個線程上! 始終是單線程!
那么問題就來了,要是在代碼插入點前的代碼執行時間超過了傳入setTimeout或setInterval的設定時間會怎樣呢?讓我們來看看這段代碼:
function fn() { setTimeout(function(){alert("can you see me?");},1000); while(true) {} }
你覺得這段代碼的執行結果是什么呢?答案是,alert永遠不會出現。
這是為什么呢?因為,while這段代碼沒有執行完(如圖,瀏覽器一直在解析while的代碼),所以插入在后面的代碼便永遠不會執行。
綜上所述,其實JS終歸是單線程產物。無論如何“異步”都不可能突破單線程這個障礙。所以許多的“異步調用”(包括Ajax)事實上也只是“偽異步”而已。只要理解了這么一個概念,也許理解setTimeout和setInterval也就不難了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/86247.html
摘要:所以其實和所謂的異步調用事實上是通過將代碼段插入到代碼的執行隊列中實現的。當執行和的時候,會根據你設定的時間準確地找到代碼的插入點。綜上所述,其實終歸是單線程產物。無論如何異步都不可能突破單線程這個障礙。 發表過一片博客《跟著我用JavaScript寫計時器》,比較基礎.....有網友說應該寫一下setTimeout的原理和機制,嗯,今天就來寫一下吧: 直奔主題:setTimeout和...
摘要:主線程會暫時存儲等異步操作,直接向下執行,當某個異步事件觸發時,再通知主線程執行相應的回調函數,通過這種機制,避免了單線程中異步操作耗時對后續任務的影響。 背景 在研究js的異步的實現方式的時候,發現了JavaScript 中的 macrotask 和 microtask 的概念。在查閱了一番資料之后,對其中的執行機制有所了解,下面整理出來,希望可以幫助更多人。 先了解一下js的任務執...
摘要:提出標準,允許腳本創建多個線程,但是子線程完全受主線程控制,且不得操作。所以,這個新標準并沒有改變單線程的本質。事件循環主線程線程只會做一件事,就是從消息隊列里面取消息執行消息,再取消息再執行。工作線程是生產者,主線程是消費者。 最近項目中遇到了一個場景,其實很常見,就是定時獲取接口刷新數據。那么問題來了,假設我設置的定時時間為1s,而數據接口返回大于1s,應該用同步阻塞還是異步?我們...
摘要:圖片轉引自的演講和兩個定時器中回調的執行邏輯便是典型的機制。異步編程關于異步編程我的理解是,在執行環境所提供的異步機制之上,在應用編碼層面上實現整體流程控制的異步風格。 問題背景 在一次開發任務中,需要實現如下一個餅狀圖動畫,基于canvas進行繪圖,但由于對于JS運行環境中異步機制的不了解,所以遇到了一個棘手的問題,始終無法解決,之后在與同事交流之后才恍然大悟。問題的根節在于經典的J...
閱讀 2955·2021-11-23 09:51
閱讀 1670·2021-10-15 09:39
閱讀 1061·2021-08-03 14:03
閱讀 2893·2019-08-30 15:53
閱讀 3441·2019-08-30 15:52
閱讀 2492·2019-08-29 16:17
閱讀 2795·2019-08-29 16:12
閱讀 1652·2019-08-29 15:26