日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

javascript --- event loop

發布時間:2023/12/10 javascript 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 javascript --- event loop 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

栗子1

  • 求下面函數的輸出
console.log('script start');setTimeout(() => {console.log('setTimeoout'); }, 0);Promise.resolve().then(function(){console.log('promise1'); }).then(function(){console.log('promise2'); }) console.log('script end');

  • 說明: 在"promise2"和"setTimeoout"之間有"<· undefined"
  • “<· undefined”: 其實是進入了下一輪事件循環
  • 可視化展示: https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

JS的執行順序

  • 原則:
  • 事件循環過程中,每次只執行1個宏任務
  • 在執行宏任務之前,首先檢查微任務隊列是否為空.若存在微任務,則先執行微任務
  • 常見的宏任務和微任務

    • 常見的宏任務: setTimeout、setInterval、setImmediate(Node)、requestAnimationFrame(瀏覽器)、I/O、UI rendering(瀏覽器)
    • 常見的微任務: process.nextTick(Node)、promise.then()、Obeject.observe、MutationObeserve

    栗子1說明:

    • 在了解了執行順序以及宏/微任務之后,再看上面的栗子1:
    • console.log('script start'): 同步任務, 輸出 ‘script start’
    • setTimeout(function(){ console.log('setTimeout') },0): 這是一個宏任務,會將函數function(){ console.log('setTimeout') }推到宏任務隊列中
    • Promise.resovle().then(function(){console.log('promise1')}).then(function(){console.log('promise2')}): 2個微任務,一次推入微任務隊列
    • console.log('script end'): 同步任務,輸出 ‘script end’
    • 到了這里,開始執行事件循環的下一輪,根據原則2.先檢擦微任務隊列是否為空,此時不為空,于是執行隊列的第一個(即輸出 ‘promise1’),然后出隊,在檢查微任務隊列是否為空(此處不為空,故輸出’promise2’,出隊),在檢查…
    • 當微任務隊列為空,代表當前事件循環結束,所以會輸出一個返回值,此處未設定,故輸出"<· undefined"
    • 從宏任務隊列中讀取,輸出(“setTimeout”)

    栗子2

    • 求以下函數的輸出結果
    new Promise(resolve => {console.log("resolve")resolve()}).then(() => console.log("promise then..."))setImmediate(() => {console.log("set immediate...") })setTimeout(() => {console.log("set Timeout ..."); }, 0);process.nextTick(() => {console.log("nextTick") })

    • 說明:
  • Promise是宏任務,其里面的函數是同步的.即會執行console.log('resolve')
  • nextTick可以理解為在其他類型微任務的前面入隊.
  • 瀏覽器中的事件循環

    • 執行全局Script的同步代碼
    • 執行microtask任務
    • 從宏任務隊列中取出隊首一個任務
    • 執行該任務
    • 任務執行完畢,檢查是否有微任務(有則執行,否則執行第一步)

    Node.js的Event Loop過程:

  • 執行全局Script的同步代碼
  • 執行microtask微任務,先執行所有 Next Tick Queue中的所有任務,再執行Other Microtask Queue中的所有任務
  • 開始執行macrotask宏任務,共6個階段,從第1個階段開始執行相應每一個階段macrotask中的所有任務,六個階段: Timers Queue -> 步驟2 -> I/O Queue -> 步驟2 -> Check Queue -> 步驟2 -> Close Callback Queue -> 步驟2 -> Timers Queue…
    • MacroTask包括: setTimeout、setInterval、setImmediate(Node)、requestAnimation(瀏覽器)、IO、UI rendering(瀏覽器)
    • MicroTask包括:s process.nextTick(Node)、Promise.then、Object.observe、MutationObserver

    setTimeout 和 setImmediate

    • setImmediate():方法用于中斷長時間運行的操作,并在完成其他操作后立即運行回調函數

    • 栗子:

    setTimeout(() => {console.log('setTimeout'); }, 0);setImmediate(() => {console.log('setImmediate'); })


    同樣的代碼執行的結果不確定:

    • setTimeout/setInterval的第二個參數取值范圍是: [1, 2^31 -1],如果超過這個范圍就會初始化為1,即 setTimeout(fn, 0) === setTimeout(fn, 1);
    • setTimeout的回調函數再timer階段執行,setImmediate的回調函數再check階段執行,event loop的開始會檢查timer階段,但是再開始之前到timer階段會消耗一定時間,就會出現以下情況:
  • timer前的準備時間超過1ms, 滿足loop -> time >=1, 則執行timer階段(setTimeout)的回調函數
  • timer前的準備時間小于1ms,則先執行check階段(setImmediate)的回調函數,下一次event loop執行timer階段(setTimeout)的回調函數
  • 栗子3

    console.time("start"); setImmediate(function() {console.log(1); }); setTimeout(function() {console.log(2); }, 10); new Promise(function(resolve) {console.log(3);resolve();console.log(4); }).then(function() {console.log(5);console.timeEnd("start") }); console.log(6); process.nextTick(function() {console.log(7); }); console.log(8);

    • 說明:
  • 首先執行script代碼,輸出3468
  • 執行nextTick任務,輸出7
  • 執行microtask, 輸出5, start: 15.232ms
  • 如果事件大于10ms,則執行宏任務 “輸出2”, 否則輸出"1"
  • 總結

    以上是生活随笔為你收集整理的javascript --- event loop的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。