国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

淺談js執行機制

jone5679 / 2576人閱讀

摘要:這種問題在設置倒計時的經常遇到,倒計時開始的時候設置的時間是從服務器拿到的系統時間很準確,但是如果后面不定期像服務期請求系統時間進行校準的話,你可能會發現倒計時的偏差越來越來大,這就是主線程執行的時間比設定的延遲時間長導致的。

關于js執行機制,老早之前就一直想寫篇文章做個總結,因為和js執行順序的面試題碰到的特別多,每次碰到總是會去網上查,沒有系統地總結,搞得每次碰到都是似懂非懂的感覺,這篇文章就系統的總結一下js執行機制。

任務隊列

大家都知道js最大的特點就是單線程執行,這就是為什么js簡單易學的一個重要原因,不需要考慮復雜的同步問題,但是單線程也會有一個問題,所有的任務在執行的過程中都必須等待前一個任務執行完成才能執行,這樣就會帶來一個效率的問題,為了解決這個問題,js將任務分為兩種:同步任務和異步任務,同步任務就是之前說后一個任務必須等待前一個任務執行完成才能執行,是在主線程上執行的,而異步任務不會直接進入主線程執行,而是進入任務隊列,只有在任務隊列通知異步任務可以執行時,才會被推入主線程執行。讓我們來看一個更加直觀的流程圖:

setTimeout和setInterval

說到異步任務,最常見就是setTimeout和setInterval兩兄弟了,setTimeout是延遲一定時間后執行,但是只執行一次,setInterval是每隔一定的時間執行一次,會執行多次,但是有時候我們會發現設置一定的延遲時間后,回調函數的執行時間會比我們設置的時間要晚,這是為什么呢?上面我們說過,在任務執行的時候setTimeout這類異步任務的回調會被放到異步隊列中等待執行,當延遲時間結束時,如果主線程的任務已經執行完了,也就是處在空閑狀態時,就會將任務隊列的回調推到主線程執行,但是當主線程的任務還沒有執行完成時,就只能繼續等待,來看一個例子:

let before = new Date()
setTimeout(() => {
  console.log(new Date() - before)
}, 1000)
for (let i = 0; i < 300000; i++) {
  console.log("time delay")
}

從上面的例子就可以看到:當我們執行完setTimeout之后,立刻執行20萬次的循環,從執行結果可以看到,setTimeout回調函數中的時間遠高于設置1000ms,這就是因為時間到了,但是主線程的任務還沒有執行完成導致。這種問題在setInterval設置倒計時的經常遇到,倒計時開始的時候設置的時間是從服務器拿到的系統時間很準確,但是如果后面不定期像服務期請求系統時間進行校準的話,你可能會發現倒計時的偏差越來越來大,這就是主線程執行的時間比設定的延遲時間長導致的。

macrotask和microtask

在js中,異步任務除了有setTimeout這類的異步任務,還有一類就是es6中很常用promise...then這類的異步任務,因此除了同步任務和異步任務,任務還可以更加細分為macrotask(宏任務)和microtask(微任務)
macrotask: 包括setTimeout、setInterval和執行棧
microtask: 包括Promise、process.nextTick
要想理解這兩個概念,直接從一道簡單的面試題入手,來看一個例子:

setTimeout(function() {
  console.log(1)
}, 0);
new Promise(function(resolve, reject) {
  console.log(2);
  resolve()
}).then(function() {
  console.log(3)
});
process.nextTick(function () {
  console.log(4)
})
console.log(5)

思考一下上面例子的輸出結果,我們來仔細分析一下執行過程:

第一輪:主線程開始執行,遇到setTimeout,將setTimeout的回調函數丟到宏任務隊列中,在往下執行new Promise立即執行,輸出2,then的回調函數丟到微任務隊列中,再繼續執行,遇到process.nextTick,同樣將回調函數扔到為任務隊列,再繼續執行,輸出5,當所有宏任務執行完成后看有沒有可以執行的微任務,發現有then函數和nextTick兩個微任務,先執行哪個呢?process.nextTick指定的異步任務總是發生在所有異步任務之前,因此先執行process.nextTick輸出4然后執行then函數輸出3,第一輪執行結束。

第二輪從宏任務隊列開始,發現setTimeout回調,輸出1執行完畢,因此結果是25431

最后用一張圖來總結一下:

總結

這篇文章簡單介紹了js執行機制,希望看了之后,可以對大家認識js的執行機制會有所幫助。
如果有錯誤或不嚴謹的地方,歡迎批評指正,如果喜歡,歡迎點贊收藏

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/100076.html

相關文章

  • 淺談JavaScript中的事件循環機制

    摘要:事件循環背景是一門單線程非阻塞的腳本語言,單線程意味著,代碼在執行的任何時候,都只有一個主線程來處理所有的任務。在意識到該問題之際,新特性中的可以讓成為一門多線程語言,但實際開發中使用存在著諸多限制。這個地方被稱為執行棧。 事件循環(Event Loop) 背景 JavaScript是一門單線程非阻塞的腳本語言,單線程意味著,JavaScript代碼在執行的任何時候,都只有一個主線程來...

    Pluser 評論0 收藏0
  • 淺談 JavaScript 運行機制

    摘要:以多線程的形式,允許單個任務分成不同的部分進行運行。提供協調機制,一方面防止進程之間和線程之間產生沖突,另一方面允許進程之間和線程之間共享資源。主線程會不斷的重復上訴過程。 眾所周知,js是單線程的,說到線程,我們首先來仔細辨析一下線程和進程的知識。 一、進程與線程 阮一峰老師的一篇文章寫的很好 cpu會給當前進程分配資源,進程是資源分配的最小單位,進程的資源會分配給線程使用,線程是C...

    URLOS 評論0 收藏0
  • 淺談不同環境下的JavaScript執行機制 + 示例詳解

    摘要:如果沒有其他異步任務要處理比如到期的定時器,會一直停留在這個階段,等待請求返回結果。執行的執行事件關閉請求的,例如事件循環的每一次循環都需要依次經過上述的階段。因此,才會早于執行。 showImg(https://segmentfault.com/img/bVbnY76); 概念 同步任務(Synchronous) 在主線程上排隊執行的任務,只有前一個任務執行完畢,才能執行后一個任務 ...

    wanghui 評論0 收藏0
  • 淺談小程序運行機制

    摘要:小程序的基礎庫不會被打包在某個小程序的代碼包里邊,它會被提前內置在微信客戶端。小程序沒有重啟的概念當小程序進入后臺,客戶端會維持一段時間的運行狀態,超過一定時間后目前是分鐘會被微信主動銷毀當短時間內連續收到兩次 寫作背景 接觸小程序有一段時間了,總得來說小程序開發門檻比較低,但其中基本的運行機制和原理還是要懂的。比如我在面試的時候問到一個關于小程序的問題,問小程序有window對象嗎?...

    Caicloud 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<