浅析javascript事件循环(eventLoop)

前言

作为浏览器脚本语言,JavaScript 的主要用途是与用户互动,以及操作 DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。

为何只能是单线程?

试想一下,假定JavaScript 同时有两个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准呢

javascript是单线程语言,如何执行异步代码

js执行异步代码机制:

1.所有任务都在主线程上执行,形成一个执行栈;

2.主线程之外,还存在一个”任务队列”(task queue)。只要异步任务有了运行结果,就在”任务队列”之中放置一个事件;

3.一旦”执行栈”中的所有同步任务执行完毕,系统就会读取”任务队列”。那些对应的异步任务,结束等待状态,进入执行栈并开始执行;

4.主线程不断重复以上3步。

宏任务(macrotask

script(整体代码)、setTimeout、setInterval、UI 渲染、 I/O、postMessage、 MessageChannel、setImmediate(Node.js 环境)

微任务

Promise.then、 MutaionObserver、process.nextTick(Node.js环境)

Event Loop(事件循环)中,每一次循环称为 tick, 每一次tick的任务如下:

1.执行栈选择最先进入队列的宏任务(通常是script整体代码);

2.检查是否存在 Microtask,如果存在则不停的执行,直至清空 microtask 队列;

3.更新render(每一次事件循环,浏览器都可能会去更新渲染)

4.重复以上步骤

实践:

```
 console.log('script start');  
 setTimeout(function () {    
    console.log("timeout");
    });
    new Promise(function(resolve,reject){
        console.log(2)
        resolve(3)
    }).then(function(val){
        console.log(val);
    })
  console.log('script end');
```
复制代码

打印顺序:script start->2->script end->3->timeout

vue源码之$nextTick ??

源码中 MutationObserver 介绍

MO是html5新的API,是用来监听DOM变动的接口,他能监听一个DOM对象上发生的子节点删除、属性修改、文本内容修改等等。

var mo = new MutationObserver(callback);
var domTarget = 你想要监听的dom节点
mo.observe(domTarget, {
      characterData: true //说明监听文本内容的修改。
})
复制代码

MutationObserver的回调(callback)是放在microtask中执行的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享