美文网首页
浏览器的Event loop

浏览器的Event loop

作者: 吴晗君 | 来源:发表于2019-04-10 23:21 被阅读0次

js为什么是单线程的?

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

所以,为了避免复杂性,从一诞生,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质。

什么是 event-loop

event loop是一种运行机制,在Javascript中用来解决单线程疲于应对多任务的问题。event loop在不同的环境中有不同的实现。如Node、各浏览器。
[图片上传失败...(image-100eb7-1554909685850)]

什么是宏任务和微任务

task的定义

An event loop has one or more task queues. A task queue is an ordered list of tasks, which are algorithms that are responsible for such work as:EventsParsingCallbacksUsing a resourceReacting to DOM manipulation
也就是说task是浏览器(或者当前运行环境)去执行Js、操作dom的一个个任务。事件触发的时候,触发的回调就会被推入这个队列中。而event loop会不断循环去获取当前task队列里的第一项拿到栈中执行。

我举个例子:我在页面上绑定了一个点击事件onClick,并且绑定了一个回调事件,这就是一个简单的发布订阅。当我的鼠标点击,触发这个事件的时候,dispatch Click这个task就会放到task queue中,而onClick回调就会被放到执行栈中执行。onClick执行完了就完成了一次event loop。浏览器(或当前运行环境)会不断去队列里取task来执行。

microtask的定义

Each event loop has a microtask queue. A microtask is a task that is originally to be queued on the microtask queue rather than a task queue.

也就是说它也是一种task,不过microtask独立有一个队列。不过它的特点是:

  1. 在上一个task完成之后,下一个task之前执行,
  2. 并且当前栈必须为空。
  3. task一样,microtask是有顺序的,不会因为后面加入的优先级高而先执行。
  4. 最后,当这个microtask执行完了,当前task才算执行完成。

microtask的用途是什么?

其中一个是减少渲染。根据HTML Standard,在每个 task 运行完以后,UI 可能会重渲染,那么比如Vue等框架在 microtask 中就完成数据更新,当前 task 结束就可以得到最新的 UI 了。反之如果新建一个 task 来做数据更新,那么渲染就会进行两次。

代码里常用的microtasktask有哪些?

task: setImmediate > messageChanel > setTimeout

microtask: then > MutationObserver

Vue.nextTick源码中有依次降级用到then、MutationObserver、setImediate、setTimeout

MessageChannel的用法

// ie10以上支持
// iframe中有用到
let channel = new MessageChannel();
let port1 = channel.port1;
let port2 = channel.port2;
console.log(port1)
console.log(port2)

// vue.nextTick 以前用这个方式实现的,废弃了
port1.onmessage = function(e){
    console.log(e.data)
};
port2.postMessage('你好');
// vue使用nextTick历史:2.5之前用micro task,2.5用macro task,2.5之后用micro task
// vue 在2.5使用macro task(也就是MessageChannel)的原因是 micro task拥有过高的优先级,
// 导致了一些bug(#4521, #6690, #6566)。setImmediate被作者任务是完美的,但只有ie和node支持
// 2.5之后改回来micro task的原因macro task引发了一些无法绕过的bug  #7109, #7153, #7546, #7834, #8109

MutationObserver的用法

// ie11以上支持
// mutationObserver是个微任务,提供了监视DOM树更改的能力
// vue 等待dom更新后 在取dom中的数据
setTimeout(()=>{
    console.log('timeout');
})
let mutationObserver = new MutationObserver((...args)=>{
     console.log(args)
     console.log(app.children.length); // 异步的
})
mutationObserver.observe(app, {childList:true})
     for(let i = 0 ; i< 10; i++){
     app.appendChild(document.createElement('p'))
}

有缘人看到这篇文章可以看一下下面参考里的第一篇文章,通读两遍,做一下里面的几个练习题,有非常详细的思路讲解,再结合HTML规范,我觉得就可以弄清楚Event loop,micro task就会用了,那些代码我就不照搬了。

参考

相关文章

  • 「JavaScript」 弄懂Event Loop

    Event loop 首先什么是Event loop, Event loop 是一个执行模型,就是说明js在浏览器...

  • event loop

    精华结论 浏览器的 Event Loop 遵循的是 HTML5 标准,而 NodeJs 的 Event Loop ...

  • JavaScript中的Event Loop小理解

    Event Loop Event Loop定义了浏览器执行你写的代码的顺序。我们都知道浏览器在执行代码的时候,并不...

  • 11.4 Node 中的 Event Loop

    11.4 Node 中的 Event Loop 问题一:Node 中的 Event Loop 和浏览器中的有什么区...

  • Event loop

    为什么要了解Event loop?理解Event loop,对于浏览器(或者nodejs)处理事件的过程会有更透彻...

  • 11.3 浏览器中的 Event Loop

    11.3 浏览器中的 Event Loop 问题一:异步代码执行顺序?解释一下什么是 Event Loop ? 上...

  • Event Loop

    什么是Event Loop? event loop是一个执行模型,在不同的地方有不同的实现。浏览器和NodeJS基...

  • 深入理解Event Loop的运行机制

    一、Event Loop是什么 Event Loop即事件循环,是指浏览器或Node.js的一种解决javaScr...

  • nodejs中的event loop

    结论 对比浏览器 想理解整个 loop 的过程,我们可以参照浏览器的 event loop,因为浏览器的比较简单,...

  • python asyncio(二)

    event_loop get_event_loop() 获取事件循环loop set_event_loop(loo...

网友评论

      本文标题:浏览器的Event loop

      本文链接:https://www.haomeiwen.com/subject/vjmeiqtx.html