国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > JavaScript > 正文

JS內(nèi)部事件機(jī)制之單線程原理

2019-11-19 13:34:50
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

任務(wù)隊(duì)列

主線程:正在執(zhí)行的代碼,會(huì)生成函數(shù)調(diào)用棧。

  • macro-task(宏任務(wù),新名:task)包括:script(整體代碼), setTimeout, setInterval, setImmediate, I/O, UI rendering。
  • micro-task(微任務(wù),新名:jobs)包括: process.nextTick, Promise, Object.observe(已廢棄), MutationObserver(html5新特性,隊(duì)列中只能有一個(gè))

任務(wù)分類(lèi)

同步任務(wù),語(yǔ)句只按語(yǔ)句先后順序執(zhí)行,前面未執(zhí)行完,不會(huì)執(zhí)行后面語(yǔ)句。

異步任務(wù),語(yǔ)句不在語(yǔ)句先后順序上執(zhí)行,執(zhí)行到該代碼時(shí),加入到相應(yīng)任務(wù)隊(duì)列,延后執(zhí)行。

單線程

主線程從 script (整體代碼)開(kāi)始第一次循環(huán)。之后全局上下文進(jìn)入函數(shù)調(diào)用棧。直到調(diào)用棧清空(只剩全局),然后執(zhí)行所有的 jobs。當(dāng)所有可執(zhí)行的 jobs 執(zhí)行完畢之后。循環(huán)再次從 task 開(kāi)始,找到其中一個(gè)任務(wù)隊(duì)列執(zhí)行完畢,然后再執(zhí)行所有的 jobs,這樣一直循環(huán)下去。

注意事項(xiàng)

  • setTimeout 最小間隔不能低于 4 毫秒,否則會(huì)自動(dòng)增加。
  • DOM 的渲染每 16 毫秒執(zhí)行一次,因?yàn)轱@示器是 60 Hz,16ms 刷新一次。
  • process.nextTick 任務(wù)會(huì)在 jobs 里單獨(dú)維護(hù)一個(gè)隊(duì)列,并且在其他 jobs 任務(wù)之前執(zhí)行。
  • 冒泡事件會(huì)直接在子元素事件執(zhí)行完成后,插入在主線程中。如果主線程不為空,那么會(huì)優(yōu)先于 jobs 執(zhí)行。

經(jīng)典示例

示例詳解:https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

通過(guò)鼠標(biāo)點(diǎn)擊

<div class="outer"> <div class="inner"></div></div>// Let's get hold of those elementsvar outer = document.querySelector('.outer');var inner = document.querySelector('.inner');// Let's listen for attribute changes on the// outer elementnew MutationObserver(function() { console.log('mutate');}).observe(outer, { attributes: true});// Here's a click listener…function onClick() { console.log('click'); setTimeout(function() {  console.log('timeout'); }, 0); Promise.resolve().then(function() {  console.log('promise'); }); outer.setAttribute('data-random', Math.random());}// …which we'll attach to both elementsinner.addEventListener('click', onClick);outer.addEventListener('click', onClick);// 輸出結(jié)果clickmutateclickmutatepromisepromisetimeouttimeout

進(jìn)階--通過(guò)js執(zhí)行

<div class="outer"> <div class="inner"></div></div>// Let's get hold of those elementsvar outer = document.querySelector('.outer');var inner = document.querySelector('.inner');// Let's listen for attribute changes on the// outer elementnew MutationObserver(function() { console.log('mutate');}).observe(outer, { attributes: true});// Here's a click listener…function onClick() { console.log('click'); setTimeout(function() {  console.log('timeout'); }, 0); Promise.resolve().then(function() {  console.log('promise'); }); outer.setAttribute('data-random', Math.random());}// …which we'll attach to both elementsinner.addEventListener('click', onClick);outer.addEventListener('click', onClick);inner.click();// 輸出結(jié)果clickclickmutatepromisepromisetimeouttimeout

由于點(diǎn)擊事件是 js 執(zhí)行的,inner 的 onClick 函數(shù)執(zhí)行完成時(shí),inner.click() 語(yǔ)句的作用域還沒(méi)有退棧,主線程調(diào)用棧不是空的,導(dǎo)致 jobs 隊(duì)列任務(wù)不會(huì)執(zhí)行,mutate 和 promise 語(yǔ)句都未能在事件循環(huán)中執(zhí)行到。從而執(zhí)行了 outer 的 onClick 函數(shù)。outer 的 onClick 函數(shù)執(zhí)行完成后,inner.click() 語(yǔ)句才退棧,繼而執(zhí)行 jobs 的任務(wù)。

只有一個(gè) mutate 是由于 jobs 隊(duì)列中,只能有一個(gè) MutationObserver 任務(wù),第二次創(chuàng)建時(shí),前一個(gè) MutationObserver 任務(wù)沒(méi)有執(zhí)行,顧不再創(chuàng)建。

總結(jié)

以上所述是小編給大家介紹的JS內(nèi)部事件機(jī)制之單線程原理,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)武林網(wǎng)網(wǎng)站的支持!

發(fā)表評(píng)論 共有條評(píng)論
用戶(hù)名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 屯留县| 巴塘县| 永嘉县| 灵武市| 桃源县| 湘阴县| 绍兴县| 那曲县| 肥西县| 自贡市| 大荔县| 宿州市| 通江县| 延吉市| 香格里拉县| 堆龙德庆县| 尤溪县| 库尔勒市| 兴和县| 满洲里市| 吐鲁番市| 麻江县| 黄石市| 乌兰察布市| 化德县| 内乡县| 库尔勒市| 阜新市| 茶陵县| 平定县| 佳木斯市| 蓬溪县| 宁晋县| 嵊州市| 澄城县| 顺昌县| 长岛县| 凯里市| 昭觉县| 江陵县| 铜鼓县|