zoukankan      html  css  js  c++  java
  • javascript与事件循环event-loop

    众所周知,JavaScript 是一门单线程语言,虽然在 html5 中提出了 Web-Worker ,但这并未改变 JavaScript 是单线程这一核心。可看HTML规范中的这段话:

    To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as described in this section. There are two kinds of event loops: those for browsing contexts, and those for workers.

    为了协调事件、用户交互、脚本、UI 渲染和网络处理等行为,用户引擎必须使用 event loops。

    任务队列

    所有的任务可以分为同步任务和异步任务,同步任务,顾名思义,就是立即执行的任务,同步任务一般会直接进入到主线程中执行;而异步任务,就是异步执行的任务,比如ajax网络请求,setTimeout 定时函数等都属于异步任务,异步任务会通过任务队列( Event Queue )的机制来进行协调。具体的可以用下面的图来大致说明一下:

    同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue 。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。

    宏任务(macrotask )和微任务(microtask )

    macrotask 和 microtask 表示异步任务的两种分类。

    主线程内的任务执行完毕,去 Event Queue 读取对应的任务,JS 引擎会将Event Queue所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。()

    宏任务和微任务之间的关系

    先看个例子

    setTimeout(() => {
        //执行后 回调一个宏事件
        console.log('内层宏事件3')
    }, 0)
    console.log('外层宏事件1');
    
    new Promise((resolve) => {
        console.log('外层宏事件2');
        resolve()
    }).then(() => {
        console.log('微事件1');
    }).then(()=>{
        console.log('微事件2')
    })
    

    我们看看打印结果

    外层宏事件1
    外层宏事件2
    微事件1
    微事件2
    内层宏事件3

    • 首先浏览器执行js进入第一个宏任务进入主线程, 遇到 **setTimeout ** 分发到宏任务Event Queue中
    • 遇到 console.log() 直接执行 输出 外层宏事件1
    • 遇到 Promise, new Promise 直接执行 输出 外层宏事件2
    • 执行then 被分发到微任务Event Queue中
    •第一轮宏任务执行结束,开始执行微任务 打印 '微事件1' '微事件2'
    •第一轮微任务执行完毕,执行第二轮宏事件,打印setTimeout里面内容'内层宏事件3'

    执行微任务,首先执行then1,输出 promise1, 然后执行 then2,输出 promise2,这样就清空了所有微任务
    执行 setTimeout 任务,输出 setTimeout 至此,输出的顺序是:script start, script end, promise1, promise2, setTimeout

  • 相关阅读:
    第七章 查询数据(待续)
    第六章 MySQL函数(待续)
    第五章 数据类型和运算符(待续)
    Centos 用户登录失败N次后锁定用户禁止登陆
    关于CentOS普通用户无法登录SSH问题
    允许FTP用户登录并禁止Shell登录的方法
    禁止Linux用户登录方法
    syslog-ng 学习心得与配置说明
    记录linux系统用户shell终端操作记录
    通过syslog接收远程日志
  • 原文地址:https://www.cnblogs.com/HelloJC/p/11188967.html
Copyright © 2011-2022 走看看