美文网首页
js事件机制(答应我耐心看)

js事件机制(答应我耐心看)

作者: 壮壮仔儿 | 来源:发表于2022-06-26 18:39 被阅读0次

event loop 决定js代码的执行顺序为了协调事件,用户交互,脚本,渲染,网络等

\color{#0580CF} {一个event loop有一个或者多个task队列。}
当用户代理安排一个任务,必须将该任务增加到相应的event loop的一个tsak队列中。

每一个task都来源于指定的任务源,比如可以为鼠标、键盘事件提供一个task队列,其他事件又是一个单独的队列。可以为鼠标、键盘事件分配更多的时间,保证交互的流畅。

task也被称为macrotask,是一个先进先出的队列,由指定的任务源去提供任务。

task/macrotask任务源:

  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI rendering

\color{#0580CF} {每一个event loop都有一个microtask队列,一个microtask会被排进microtask队列而不是task队列。}
microtask 队列和task 队列有些相似,都是先进先出的队列,由指定的任务源去提供任务,不同的是一个
event loop里只有一个microtask 队列。
microtask任务源:

  • process.nextTick
  • promises
  • Object.observe
  • MutationObserver

event loop的循环过程:

  1. 在tasks队列中选择最老的一个task,用户代理可以选择任何task队列,如果没有可选的任务,则跳到下边的microtasks步骤。
  2. 将上边选择的task设置为正在运行的task。
  3. Run: 运行被选择的task。
  4. 将event loop的currently running task变为null。
  5. 从task队列里移除前边运行的task。
  6. Microtasks: 执行microtasks任务检查点。(也就是执行microtasks队列里的任务)
  7. 更新渲染(Update the rendering)...
  8. 如果这是一个worker event loop,但是没有任务在task队列中,并且WorkerGlobalScope对象的closing标识为true,则销毁event loop,中止这些步骤,然后进行定义在Web workers章节的run a worker。
  9. 返回到第一步。

概括:
\color{#0580CF} {event loop会不断循环的去取tasks队列的中最老的一个任务推入栈中执行,}
\color{#0580CF} {并在当次循环里依次执行并清空microtask队列里的任务。}

\color{#0580CF} {执行完microtask队列里的任务,有可能会渲染更新。}
\color{#0580CF} {浏览器很聪明,在一帧以内的多次dom变动浏览器不会立即响应,而是会积攒变动以最高60HZ的频率更新视图}

microtasks检查点(microtask checkpoint)

  1. 将microtask checkpoint的flag设为true。
  2. Microtask queue handling: 如果event loop的microtask队列为空,直接跳到第八步(Done)。
  3. 在microtask队列中选择最老的一个任务。
  4. 将上一步选择的任务设为event loop的currently running task。
  5. 运行选择的任务。
  6. 将event loop的currently running task变为null。
  7. 将前面运行的microtask从microtask队列中删除,然后返回到第二步(Microtask queue handling)。
  8. Done: 每一个environment settings object它们的 responsible event loop就是当前的event loop,会给environment settings object发一个 rejected promises 的通知。
  9. 清理IndexedDB的事务。
  10. 将microtask checkpoint的flag设为flase。

task和microtask都是推入栈中执行的,

主线程类似一个加工厂,它只有一条流水线,待执行的任务就是流水线上的原料,只有前一个加工完,后一个才能进行。event loops就是把原料放上流水线的工人。只要已经放在流水线上的,它们会被依次处理,称为同步任务。一些待处理的原料,工人会按照它们的种类排序,在适当的时机放上流水线,这些称为异步任务。

setTimeout(function() {
    console.log('setTimeout');
})

new Promise(function(resolve) {
    console.log('promise');
}).then(function() {
    console.log('then');
})

console.log('console');

task:script microtask:

取出script推入栈中执行,promise立即执行以及打印

settimeout为task,then为microtask

【task队列:settimeout;microtask队列:then】

执行microtask,进行下一项

从task队列取出settimeout,推入栈中执行

console.log('1');

setTimeout(function() {
    console.log('2');
    process.nextTick(function() {
        console.log('3');
    })
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})
process.nextTick(function() {
    console.log('6');
})
new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
    process.nextTick(function() {
        console.log('10');
    })
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})

task:script microtask:

取出script推入栈中执行,打印1,setTimeout为task,nextTick为microtask,打印7,then为microtask,setTimeout为task

【task队列:settimeout1 setTimeout2 ;microtask队列:nextTick then】

执行microtask打印6以及8,进行下一项

【task队列:setTimeout1 setTimeout2;microtask队列:】

从task队列取出settimeout1,推入栈中执行,打印2,setTimeout-nextTick为microtask,立即执行Promise打印4,setTimeout-then为microtask

【task队列:setTimeout2;microtask队列: setTimeout-nextTick setTimeout-then】

执行microtask打印3以及5,进行下一项

【task队列:setTimeout2;microtask队列:】

从task队列取出settimeout2,推入栈中执行,打印9,setTimeout2-nextTick为microtask,立即执行Promise打印11,setTimeout2-then为microtask

【task队列:;microtask队列:setTimeout2-nextTick setTimeout2-then】

打印打印10,打印12

相关文章

  • js事件机制(答应我耐心看)

    event loop 决定js代码的执行顺序为了协调事件,用户交互,脚本,渲染,网络等 当用户代理安排一个任务,必...

  • 事件处理机制

    Node.js事件触发对象有哪些方法? 详细讲讲Node.js事件机制是怎样的? Node.js事件机制和Java...

  • javascript 中的事件机制

    js之事件机制 1、事件初探 1.1 js事件的概述 JavaScript事件:JavaScript是基于事件驱动...

  • 20、jQuery 事件机制

    20、jQuery 事件机制 原生js事件与jQuery事件: (1)用原生的js给div注册事件 原生js注册相...

  • 2019-03-28

    JS 事件循环机制 - 任务队列、web API、JS主线程的相互协同 这篇文章的核心是分析js的事件循环,在此我...

  • 性能优化——事件代理

    了解过JS的事件机制应该知道JS的事件触发后会有一个冒泡阶段。事件代理就是利用了这个机制。 我们考虑这样一个情况 ...

  • JavaScript的事件机制详解

    【js事件详解】js事件封装函数,js跨浏览器事件处理机制 一、事件流 事件流描述的是从页面中接受事件的顺序。IE...

  • JS 事件(2)

    1、事件传播机制、阻止传播、取消默认事件、事件代理这些到底是什么呢? ①事件传播机制:JS事件传播包括三个阶段: ...

  • js事件机制

    一、js事件机制三个阶段:事件捕获、事件目标处理函数、事件冒泡 js中事件执行的整个过程称之为事件流,分为三个阶段...

  • JS事件机制

    事件流 事件流指从页面接收事件的顺序,分为冒泡(IE)和捕获 'DOM2级事件'规定的事件流包括三部分:捕获、处于...

网友评论

      本文标题:js事件机制(答应我耐心看)

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