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

歡迎訪問 生活随笔!

生活随笔

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

javascript

hook 循环点击事件用哪个_JS 事件循环 event loop,看完你可以答对 90% 的事件循环题...

發(fā)布時間:2024/9/27 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 hook 循环点击事件用哪个_JS 事件循环 event loop,看完你可以答对 90% 的事件循环题... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文不保證能說明透徹,因為它本來就存在著混亂,但力求講到點子上。

比較下面這幾個的執(zhí)行順序setTimeout

setInterval

setImmediate (nodejs 支持,

new Promise(cb) 和 promise.then(cb)(promise 是 Promiose 的實例)

process.nextTick(nodejs)

還有一些另外的(暫時不考慮)socket.on('close', cb) close callback(nodejs)

分類

同步執(zhí)行

new Promise(cb) cb 代碼會同步執(zhí)行,其實不屬于考慮范疇了

microTask 微任務process.nextTick tickTask

promise.then(cb) microTask

microTask (在 nodejs)可以進一步劃分為 tickTask 和 microTask,都是微任務隊列,同類型的微任務先進先執(zhí)行

優(yōu)先級是 tickTask > microTask

macroTask 宏任務setTimeout

setInterval 優(yōu)先級同 setTimeout,誰先被推到 timers 隊列誰就先執(zhí)行

setImmediate

在不同類型宏任務切換的間隙,一旦微任務隊列有任務則會把微任務隊列先執(zhí)行完,然后繼續(xù)執(zhí)行下一個類型的宏任務隊列。(注意是切換的時候,如果已經(jīng)進入執(zhí)行階段是讓該類型的宏任務執(zhí)行完然后檢查微任務隊列,如果宏任務執(zhí)行時又加入了同類型的宏任務,則會在下一個循環(huán)里面執(zhí)行)

進入 timers 或者 check 或者其他的宏任務隊列時,如果 microTask 任務隊列中沒有任務,則會在執(zhí)行完優(yōu)先執(zhí)行的宏任務隊列之后再檢查 microTask 任務隊列(注意:如果某個 macroTask 執(zhí)行時推入了新的 microTask,它依然會先把這個類型的宏任務隊列執(zhí)行完,然后切換下一個類型宏任務隊列時先執(zhí)行微任務),如果有則執(zhí)行完 microTask,然后進入下一個類型的 macroTask 隊列

這里有一個非確定情況,setImmediate 和 setTimeout 的執(zhí)行順序在 nodejs 中不是固定的(nodejs 開發(fā)者這么說)。? For example, if we run the following script which is not within an I/O cycle (i.e. the main module), the order in which the two timers are executed is non-deterministic, as it is bound by the performance of the process

做個測試,下面的執(zhí)行是不確定的,沒有實際的意義

setTimeout(() => {

console.log('1 setTimeout')

setTimeout(() => {

console.log('2 setTimeout')

}, 0)

setImmediate(() => {

console.log('3 setImmediate')

})

}, 0)

setImmediate(() => {

console.log('4 setImmediate')

})

nodejs

可能

4 setImmediate

1 setTimeout

3 setImmediate

2 setTimeout

也可能

1 setTimeout

4 setImmediate

3 setImmediate

2 setTimeout

setTimeout 有一個隱形前提,它的第二個參數(shù),也就是延遲執(zhí)行的時間,最小是 4ms,即使指定的 0,另外注意它是 n ms 之后才可能執(zhí)行,并不是 n ms 時就會執(zhí)行,它的執(zhí)行時間是不確定的,只能知道在 n ms 之前它不會執(zhí)行。

setInterval 回調內如果是一個 while 循環(huán),即使時間設定的 0,它也不會推無限多個回調到 timers 隊列中,而是要等到這個執(zhí)行完,才會把下一個回調推入 timers 隊列,用 while 執(zhí)行 2S 之后,清除掉 interval,發(fā)現(xiàn)回調只執(zhí)行了一次,而不是執(zhí)行很多次。

看下面的例子,這說明 setInterval 會推一個回調到 timers 隊列,然后執(zhí)行,然后再推下一個回調。

let count = 0

setTimeout(() => {

console.log('1 setTimeout')

}, 0)

const i = setInterval(() => {

console.log('2 setInterval')

count++

if (count === 5) {

clearInterval(i)

}

setTimeout(() => {

console.log('3 setTimeout ', count)

}, 0)

}, 0)

setTimeout(() => {

console.log('4 setTimeout')

}, 0)

---

1 setTimeout

2 setInterval

4 setTimeout

3 setTimeout 1

2 setInterval

3 setTimeout 2

2 setInterval

3 setTimeout 3

2 setInterval

3 setTimeout 4

2 setInterval

3 setTimeout 5

nodejs 事件循環(huán)

上述基本都是 macroTask 宏任務

setTimeout(() => {

console.log('1 setTimeout')

setTimeout(() => {

console.log('2 setTimeout')

}, 0)

setImmediate(() => {

console.log('3 setImmediate')

})

setTimeout(() => {

console.log('4 setTimeout')

}, 0)

setImmediate(() => {

console.log('5 setImmediate')

})

}, 0)

這個結果說明執(zhí)行過程是整個隊列執(zhí)行完再執(zhí)行下一個隊列下面結果說明在同一事件循環(huán)內, check 隊列會執(zhí)行完之后再去執(zhí)行 timers 隊列。(check 未必比 timers 快)

1 setTimeout

3 setImmediate

5 setImmediate

2 setTimeout

4 setTimeout

如果在 check 隊列執(zhí)行期間推入 microTask 任務,那就先讓當前 check 隊列執(zhí)行完,然后再執(zhí)行 microTask,再執(zhí)行 timers 隊列。

setTimeout(() => {

console.log('1 setTimeout')

setTimeout(() => {

console.log('2 setTimeout')

}, 0)

setImmediate(() => {

console.log('3 setImmediate')

new Promise(res => res()).then(() => {

console.log('4 promise')

})

process.nextTick(() => {

console.log('5 nextTick')

})

})

setTimeout(() => {

console.log('6 setTimeout')

}, 0)

setImmediate(() => {

console.log('7 setImmediate')

})

}, 0)

執(zhí)行結果,兩個 setImmediate 被放到 check 隊列,check 隊列中的 setImmediate 要先全部執(zhí)行完,然后再下一步,而下一步過程中 microTask 就會執(zhí)行。

1 setTimeout

3 setImmediate

7 setImmediate

5 nextTick

4 promise

2 setTimeout

6 setTimeout

注意下面代碼和上面代碼的區(qū)別

setTimeout(() => {

console.log('1 setTimeout')

setTimeout(() => {

console.log('2 setTimeout')

}, 0)

setImmediate(() => {

console.log('3 setImmediate')

})

new Promise(res => res()).then(() => {

console.log('4 promise')

})

process.nextTick(() => {

console.log('5 nextTick')

})

setTimeout(() => {

console.log('6 setTimeout')

}, 0)

setImmediate(() => {

console.log('7 setImmediate')

})

}, 0)

---

1 setTimeout

5 nextTick

4 promise

3 setImmediate

7 setImmediate

2 setTimeout

6 setTimeout

題目

題目 1

setTimeout setInterval 是不是相同優(yōu)先級?是否被推到同一個隊列

setTimeout(() => {

console.log('1 timeout')

}, 0)

setInterval(() => {

console.log('2 interval')

}, 0)

setTimeout(() => {

console.log('3 timeout')

}, 0)

setInterval(() => {

console.log('4 interval')

}, 0)

setTimeout(() => {

console.log('5 timeout')

}, 0)

題目 2

setTimeout(() => {

console.log('1 setTimeout')

setTimeout(() => {

console.log('2 setTimeout')

}, 0)

setImmediate(() => {

console.log('3 setImmediate')

setImmediate(() => {

console.log('4 setImmediate')

})

process.nextTick(() => {

console.log('5 nextTick')

})

})

setImmediate(() => {

console.log('7 setImmediate')

})

setTimeout(() => {

console.log('8 setTimeout')

}, 0)

}, 0)

總結

微任務(microTask)是大爺,宏任務(macroTask)得讓著微任務,但是一旦讓一個類型的宏任務開始執(zhí)行,那就得等這個類型的宏任務執(zhí)行完,然后才能執(zhí)行微任務!!!在宏任務中被推入隊列的宏任務得在下一輪才能開始執(zhí)行,這一輪沒新宏任務的份。

歡迎大家關注我的掘金和公眾號,算法、TypeScript、React 及其生態(tài)源碼定期講解。

總結

以上是生活随笔為你收集整理的hook 循环点击事件用哪个_JS 事件循环 event loop,看完你可以答对 90% 的事件循环题...的全部內容,希望文章能夠幫你解決所遇到的問題。

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