zoukankan      html  css  js  c++  java
  • 消息队列和事件循环

    每个渲染进程都有一个主线程,并且主线程非常繁忙,既要处理DOM,又要计算样式,还要处理布局,同时还需要处理JavaScript任务以及各种输入事件。为了让这些不同类型的任务在主线程中有条不紊的执行,就需要一个系统来统筹调度这些任务,这个统筹调度系统就是消息队列和事件循环系统

    第一版:使用单线程处理安排好的工作

    ​ 线程的一次执行

    第二版:在线程中引入事件循环

    原因:并不是所有的任务都是在执行之前统一安排好的,大部分情况下,新的任务是在线程运行过程中产生的。

    解决:要想在线程运行过程中,能接收并执行新的任务,就需要采用事件循环机制。即:

    • 引入了循环机制,具体实现方法是在线程语句最后添加了一个for循环语句,线程会一直循环执行。
    • 引入了事件,可以在线程运行过程中,等待用户输入的数字,等待过程中线程处于暂停状态,一旦接收到用户输入的信息,那么线程会被激活,然后执行相加运算,最后输出结果。

    ​ 在线程中引入事件循环

    第三版:队列 + 循环

    原因:在第二版的线程模型中,所有的任务都是来自于线程内部的,如果另外一个线程想让主线程执行一个任务,第二版的线程模型无法做到。

    解决:使用消息队列

    消息队列是一种数据结构,可以存放要执行的任务。符合队列“先进先出”的特点

    从上图可以看出,改造分三步:

    • 添加一个消息队列
    • IO线程中产生的新任务添加进消息队列尾部
    • 渲染主线程会循环地从消息队列头部中读取任务,执行任务。

    跨进程发送消息

    从图中可以看出,如果其他进程想要发送任务给页面主线程,那么先通过IPC把任务发送给渲染进程的IO线程,IO线程再把任务发送给页面主线程。

    页面主线程如何安全退出

    在Chrome中,当页面主线程执行完成后,确定要退出当前页面时,页面主线程会设置一个退出标志的变量,在每次执行完后判断是否有退出标志,若有,则直接中断当前的所有任务。

    页面使用单线程的缺点

    • 如何处理高优先级的任务

    若采用观察者模式,设计监听接口,则影响执行效率。若采用异步,则影响实时性。

    解决方案:微任务

    通常我们把消息队列中的任务称为宏任务,每个宏任务中都包含了一个微任务队列,在执行宏任务的过程中,如果 DOM 有变化,那么就会将该变化添加到微任务列表中,这样就不会影响到宏任务的继续执行,因此也就解决了执行效率的问题。

    等宏任务中的主要功能都直接完成之后,这时候,渲染引擎并不着急去执行下一个宏任务,而是执行当前宏任务中的微任务,因为 DOM 变化的事件都保存在这些微任务队列中,这样也就解决了实时性问题。

    • 如何解决单个任务执行时长过久,导致卡顿的问题

    解决方案:JavaScript通过回调功能来规避这种问题,也就是让要执行的JavaScript任务滞后执行。

    微任务

    • 为什么需要微任务?

    因为 JavaScript 代码不能掌控宏任务添加到队列中的位置,难以控制开始执行任务的时间。对时间精度要求较高的需求,宏任务难以胜任,所以需要微任务。

    • 什么是微任务?

    微任务是一个需要异步执行的函数,执行时机是在主函数执行结束之后、当前宏任务结束之前

    • 如何产生微任务?

      • 使用 MutationObserver 监控某个 DOM 节点,然后再通过 JavaScript 来修改这个节点,或者为这个节点添加、删除部分子节点,当 DOM 节点发生变化时,就会产生 DOM 变化记录的微任务。

      • 使用 Promise,当调用Promise.resolve()或者Promise.reject()的时候,也会产生微任务。

    • 微任务和宏任务

      • 微任务和宏任务是绑定的,每个宏任务在执行时,会创建自己的微任务队列。

      • 微任务的执行时长会影响到当前宏任务的时长。

      • 在一个宏任务中分别创建一个用于回调的宏任务和微任务,无论什么情况下,微任务都早于宏任务执行。

    宏任务是开会分配的工作内容,微任务是工作过程中被临时安排的内容

  • 相关阅读:
    codeforces 447C. DZY Loves Sequences 解题报告(446A)
    ajax 请求多张图片数据
    window 常用软件
    linux 脚本命令匹配并获取下一行数据
    linux C之getchar()非阻塞方式
    php curl 库使用
    vue.js 简单入门
    巧用jQuery选择器写表单办法总结(提高效率)
    linux 中断理解
    linux 驱动 工作队列
  • 原文地址:https://www.cnblogs.com/zpsakura/p/13885400.html
Copyright © 2011-2022 走看看