资讯专栏INFORMATION COLUMN

js事件循环

elarity / 2326人阅读

摘要:每一个程序都拥有唯一的事件循环,大多数代码的执行顺序是可以根据函数调用栈的规则执行的,而或者不同的事件绑定等中的代码,则通过队列来执行。当所有可执行的执行完毕之后,就表示第一次事件循环结束第二次循环会再次从开始执行。

console.log("begin");
setTimeout(function() { console.log("timeout") });
new Promise(function(resolve) {
    for (let i = 0; i < 3; i++) {
        if (i == 1) resolve();
        console.log(i);
    }
    console.log("promise")
}).then(function() {
    console.log("then")
})
console.log("end");

上述代码依次输出:begin、0、1、2、promise、end、then、timeout

js的一个特点就是单线程,但是很多时候我们仍然需要在不同的时间去执行不同的任务,例如给元素添加点击事件,设置一个定时器,或者发起ajax请求,因此需要一个异步机制来达到这样的目的,事件循环机制也因此而来。

每一个js程序都拥有唯一的事件循环,大多数代码的执行顺序是可以根据函数调用栈的规则执行的,而setTimeout/setInterval或者不同的事件绑定(click、mousedown等)中的代码,则通过队列来执行。

任务队列又分为宏任务(macro-task)与微任务(micro-task)两种,在浏览器中,包括:

macro-task:script(整体代码)、setTimeout/setInterval、I/O、UI rendering等

micro-task:Promise、MutationObserver

事件循环的顺序,决定了js代码的执行顺序:
首先从macro-task中的script开始第一次循环。此时全局上下文进入函数调用栈,直到调用栈清空,在这个过程中,如果遇到任务分发器(例如timer、promise),就会将任务放入对应队列中去

第一次循环时,macro-task中其实只有script,因此函数调用栈清空之后,会直接执行所有的micro-task。当所有可执行的micro-task执行完毕之后,就表示第一次事件循环结束

第二次循环会再次从macro-task开始执行。此时macro-task中的script队列已经没有任务了,但是可能会有其他的队列任务,而micro-task中暂时还没有任务。此时会先选择其中一个宏任务队列,例如setTimeout,将该队列中所有的任务全部执行完毕,然后再执行此过程中可能产生的微任务。微任务执行完毕之后,再回过头来执行其他宏任务队列中的任务。以此类推,直到所有宏任务队列中的任务都被执行了,并且清空了微任务,第二次循环就会结束

如果在第二次循环过程中,产生了新的宏任务队列,或者之前宏任务队列中的任务暂时没有满足执行条件,例如延迟时间不够或者事件没有被触发,那么将会继续以同样的顺序重复循环

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/105627.html

相关文章

  • [译]事件循环,Node.js背后的核心概念

    摘要:事件处理器,则是当指定事件触发时,执行的一段代码。事件循环以一个无限循环的形式启动,存在于二进制文件里函数的最后,当没有更多可被执行的事件处理器时,它就退出。 前言 如果你了解过Node.js,那么你一定听说过事件循环。你一定想知道它为什么那么特殊,并且为什么你需要关注它?此时此刻的你,可能已经写过许多基于Express.js的后端代码,但没有接触到任何的循环。 在下文中,我们会先在一...

    Meils 评论0 收藏0
  • Node.js 指南(Node.js事件循环、定时器和process.nextTick())

    摘要:检索新的事件执行与相关的回调几乎所有,除了由定时器调度的一些和将在适当的时候在这里阻塞。在事件循环的每次运行之间,检查它是否在等待任何异步或定时器,如果没有,则彻底关闭。 Node.js事件循环、定时器和process.nextTick() 什么是事件循环? 事件循环允许Node.js执行非阻塞I/O操作 — 尽管JavaScript是单线程的 — 通过尽可能将操作卸载到系统内核。 ...

    pingink 评论0 收藏0
  • JavaScript事件循环(Event Loop)

    摘要:事件循环的顺序,决定代码执行的顺序。输出第二轮事件循环正式结束三第三轮事件循环第三轮事件循环从宏任务开始。记为遇到,立即执行回调函数放入中注册,然后被分发到微任务事件队列中。 1、为什么要有事件循环? 因为js是单线程的,事件循环是js的执行机制,也是js实现异步的一种方法。 既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也要一个一个顺序执行。如...

    dmlllll 评论0 收藏0
  • 【笔记】 你不知道的JS读书笔记——异步

    摘要:异步请求线程在在连接后是通过浏览器新开一个线程请求将检测到状态变更时,如果设置有回调函数,异步线程就产生状态变更事件,将这个回调再放入事件循环队列中。 基础:浏览器 -- 多进程,每个tab页独立一个浏览器渲染进程(浏览器内核) 每个浏览器渲染进程是多线程的,主要包括:GUI渲染线程 JS引擎线程 也称为JS内核,负责处理Javascript脚本程序。(例如V8引擎) JS引擎线程负...

    junnplus 评论0 收藏0
  • Javascript事件循环机制以及渲染引擎何时渲染UI

    摘要:的一大特点就是单线程,而这个线程中拥有唯一的一个事件循环。事件循环基本概念代码的执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外,还依靠任务队列来搞定另外一些代码的执行。之后全局上下文进入函数调用栈。 JavaScript的一大特点就是单线程,而这个线程中拥有唯一的一个事件循环。 事件循环基本概念 JavaScript代码的执行过程中,除了依靠函数调用栈来搞定函数的执行顺序外,还...

    cnio 评论0 收藏0
  • 真正理解 Node.js事件循环

    摘要:轮询投票处理下一次处理的新事件立即设置运行通过注册的所有回调关闭执行所有的回调工作处理延迟此度量标准测量线程池处理异步任务需要多长时间。高工作时间处理延迟表明繁忙耗尽的线程池。 原文=> What you should know to really understand the Node.js Event Loop Node.js 是一个基于事件的平台。这就意味着在Node中发生的所...

    GeekGhc 评论0 收藏0

发表评论

0条评论

elarity

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<