chrome事件循环的自问自答

这篇具有很好参考价值的文章主要介绍了chrome事件循环的自问自答。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

chrome事件循环的自问自答

目录

  • 1. 宏任务有哪些?
  • 2. 微任务有哪些?
  • 3. dom渲染是事件循环的一部分么?
  • 4. requestAnimationFrame的回调是宏任务还是微任务?
  • 5. requestIdleCallback的回调是宏任务还是微任务?
  • 6. 事件循环图例

1. 宏任务有哪些?

  • 事件回调 (js调用的 click box.click()
  • XHR或网络请求回调
  • 定时器的回调
  • I/O回调
  • history相关回调
  • MessageChannel的message回调

在合适时机,这些宏任务会被推入宏任务队列;每一次事件循环会从宏任务队列中取一个任务执行。

history.back回调:

<button id='box'>forward</button>
<button id='box2'>back</button>

<script>
  var box = document.getElementById('box');
  var box2 = document.getElementById('box2');
  box.addEventListener('click',()=>{
    history.pushState('state',null,'?page=1');
  })

  window.addEventListener('popstate',function (ev) {
    console.log('popstate');
  })
  box2.addEventListener('click',()=>{
    history.back();
    setTimeout(()=>{
      console.log('timeout');
    })
  })
</script>

MessageChannel的message回调

<button id='btn'>btn</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
  var channel = new MessageChannel();
    channel.port1.onmessage = function onmessage1 (){
      console.log('postMessage')
      Promise.resolve().then(function promise1 (){
          console.log('promise')
      })
    };
    setTimeout(function setTimeout2(){
      console.log('setTimeout')
    }, 0)
    channel.port2.postMessage(0);
};
</script>

I/O回调

<input type="file" id="input" multiple>
<script>
  input.addEventListener('change', function () {
    var file = input.files[0]
    var reader = new FileReader()
    reader.onload = function (ev) {
      console.log(reader.result);
    }
    reader.readAsArrayBuffer(file)
  })
</script>

2. 微任务有哪些?

MutationObserver的回调、Promise的then catch finally回调、queueMicrotask.

在合适时机,这些微任务会被推入微任务队列;每一次事件循环会从微任务队列中取所有任务并执行。

Promise和queueMicrotask不支持IE, MutationObserver支持IE11;

MutationObserver例子:

下面的代码中box.textContent = 1的位置不同,代码的执行顺序就不同以验证MutationObserver为微任务。

<div id='box'>0</div>
<script>
  const box = document.getElementById('box');
  const mo = new MutationObserver(function (mutations) {
    console.log('mutations')
  })
  mo.observe(box, {
    childList: true
  })
  box.onclick = function () {
    // box.textContent = 1;
    Promise.resolve().then(()=>{
      console.log(333)
    })
    box.textContent = 1;
  };
</script>

以下是使用`queueMicrotask`方法手动添加微任务的例子,可以不会对更高优先级的代码运行造成干扰。

<div id='box'>0</div>
<script>
  const box = document.getElementById('box');
  box.onclick = function () {
    queueMicrotask(()=>{
      console.log(121212)
    })
    console.log(333)
  };
</script>

3. dom渲染是事件循环的一部分么?

从规范的角度来看,DOM渲染是事件循环的一部分,可以将其视为一种渲染任务。

如果宏任务或者微任务中发生了dom修改,因为一个渲染帧的时间可能远大于事件循环周期,所以不一定在本次事件循环会执行渲染任务。

<div id='box'>0</div>
<script>
  const box = document.getElementById('box');
  box.onclick = function () {
    setTimeout(function setTimeout17 () {
      box.textContent = 1;
    }, 0)
    setTimeout(function setTimeout18 () {
      box.textContent = 2;
    }, 0)
  };
</script>

下图是上面的代码的执行流程,两个setTimeout的回调执行代表两次事件循环,在其后面出现了一个新的Task,仅执行了一次布局(layout)和绘制(paint);

chrome事件循环的自问自答

4. requestAnimationFrame的回调是宏任务还是微任务?

requestAnimationFrame的回调函数会在浏览器在下一帧渲染之前执行, 既不是宏任务,也不是微任务, 从规范上看是事件循环的一部分,从下图可以看到一个task下包含了requestAnimationFrame,layout paint, 可将其归类于渲染任务的一个可选步骤。

<div id='box'>0</div>
<script>
  const box = document.getElementById('box');
  box.onclick = function () {
    setTimeout(function setTimeout17 () {
      box.textContent = 1;
      requestAnimationFrame(()=>{
        console.log(111)
         Promise.resolve().then(()=>{
          console.log(333)
        })
      })
    }, 0)
    setTimeout(function setTimeout18 () {
      box.textContent = 2;
      requestAnimationFrame(()=>{
        console.log(222)
      })
    }, 0)
  };
</script>

上述代码中添加了两个requestAnimationFrame,可以看到两者在一个Task内顺序执行;并且回调中的微任务也在这个Task内执行;

chrome事件循环的自问自答

5. requestIdleCallback的回调是宏任务还是微任务?

requestIdleCallback是事件循环的一部分,从图中可以看到,requestIdleCallback的回调是一个特殊的任务,这个函数的回调会在浏览器空闲时期被调用,所以不是每次循环都会执行该任务。

<button id='btn'>btn</button>
<script>
var btn = document.getElementById('btn');
btn.onclick = function () {
  requestIdleCallback(function () {
    btn.innerHTML = "sdfsdfs"
    setTimeout(()=>{
      console.log(3)
    },0)
    Promise.resolve().then(()=>{
      console.log(4)
    })
  })
};
</script>

chrome事件循环的自问自答

该任务的优先级比较低,多个平行声明的requestIdleCallback会拆开成单一的task, 两个连续task之间甚至会被内部的setTimeout插足。

for (let i = 0; i < 10; i++) {
  requestIdleCallback(() => {
    console.log('idle', Date.now() - a)
    setTimeout(()=>{
      console.log(12121)
    })
  })
}

chrome事件循环的自问自答

6. 事件循环图例

chrome事件循环的自问自答文章来源地址https://www.toymoban.com/news/detail-590273.html

到了这里,关于chrome事件循环的自问自答的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 事件循环机制

    聊一下事件循环机制,在开始这篇文章之前,先明确一个概念,js本身是没有事件循环这个定义的。是js被嵌入相应的执行环境(浏览器 / Nodejs),配合当前事件循环的组成部分,具体来说分下面两部分: 在浏览器环境中,事件循环是HTML标准中定义的,用于协调浏览器端的多

    2024年02月08日
    浏览(55)
  • js事件循环详解

    JavaScript的事件循环是一种处理异步事件和回调函数的机制,它是在浏览器或Node.js环境中运行,用于管理任务队列和调用栈,以及在适当的时候执行回调函数。 事件循环的基本原理是,JavaScript引擎在空闲时等待事件的到来,然后将事件添加到事件队列中。事件循环会不断地检

    2024年02月07日
    浏览(36)
  • 事件循环

    事件循环与浏览器有关,需要先了解其进程模型。 程序运行需要其专属的内存空间,用于存储变量、执行函数等操作,可以将这块内存空间简单地理解为进程。 每个应用 至少有一个进程 ,进程之间 相互独立 ,即使要通信,也需要双方同意。 有了进程后,就可以运行程序的

    2024年02月08日
    浏览(22)
  • 事件循环原理

    何为进程? 程序运行需要有它自己专属的内存空间,可以把这块内存空间简单的理解为进程 每个应用至少有一个进程,进程之间相互独立,即使要通信,也需要双方同意。 何为线程? 有了进程后,就可以运行程序的代码了。 运行代码的「人」称之为「线程」。 一个进程至

    2024年02月14日
    浏览(33)
  • chrome浏览器技巧,如何查看web页面上元素绑定的监听事件

    第一步:首先通过 F12 进入开发者工具页面。 第二步:选中 Elements 页签内对应的元素,可以用一个按钮来试一试。 第三步:右边选择 Event Listeners 页签,并取消勾选 Ancestors All。这个包含该元素所有父类绑定的监听事件。 如下图所示:图中的提示框的确定按钮就绑定了一个

    2024年02月13日
    浏览(49)
  • AJAX: 事件循环(举例细论)

    概念 :执行任务和收集异步任务,在调用栈空闲时,反复调用任务队列里回调函数的一种执行机制 原因 :JavaScript 是单线程的,为了不阻塞 JS 引擎,设计执行代码的模型 JS内代码如何执行 : 执行同步代码,遇到异步代码就交给宿主浏览器环境执行。异步有了结果之后,把

    2024年02月16日
    浏览(24)
  • 在?聊聊浏览器事件循环机制

    目录 前言  同步/异步编程模型 同步 异步 JS异步模型 调用栈 任务队列 宏任务队列 微任务队列 微任务API 事件循环 队列优先级 混合队列 事件循环实现 总结 参考文章 Event-Loop可视化工具 JS是单线程语言,在某个时间段只能执行一段代码。这种单线程模型的好处是不会出现多

    2024年02月10日
    浏览(64)
  • 浏览器事件循环Event Loop

    引言: 事件循环不是浏览器独有的,从字面上看,“循环”可以简单地认为就是重复,比如for循环,就是重复地执行for循环体中的语句,所以事件循环,可以理解为重复地处理事件,那么下一个问题是,处理的是什么事件,事件的相关信息从哪里获取。 因为我没有用nodejs做

    2024年02月05日
    浏览(52)
  • Qt事件循环及QEventLoop的使用

    目录 一、  Qt的事件循环 二、QCoreApplication 主事件循环 三、事件循环的开启 四、Qt中父子事件传递 1、例子 五、processEvents 六、QEventLoop类 七、事件循环的嵌套及QEventLoop模拟同步调用 1、同步获取数据 2、主线程等待 3、对话框弹出         Qt作为一个跨平台的UI框架,其事件

    2023年04月08日
    浏览(18)
  • 33、js - 事件循环 微任务 宏任务

    js是 单线程语言 ,也就是某一刻只能执行一行代码,为了让耗时代码不阻塞其他代码运行,设计了 事件循环模型 。 事件循环是一个并发模型,负责执行代码、收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫事件循环。 这个模型与其他

    2024年02月08日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包