理解JS中的Event Loop机制[亲测有效]

理解JS中的Event Loop机制[亲测有效]前几天在理解node的事件环机制中引发了我对浏览器里Event Loop的好奇。我们都知道javascript是单线程的,任务是需要一个一个按顺序执行的,如果javascript有两个线程,一个为DOM增加样式,一个却要删除DOM,这样岂不是就会很混乱。单线程可以节约内存,但是…

前言

前几天在理解node的事件环机制中引发了我对浏览器里Event Loop的好奇。我们都知道javascript是单线程的,任务是需要一个一个按顺序执行的,如果javascript有两个线程,一个为DOM增加样式,一个却要删除DOM,这样岂不是就会很混乱。单线程可以节约内存,但是必须等待前一个任务完成后才能执行下一个任务。接下来理解浏览器中的Event Loop,先看一张图:

理解JS中的Event Loop机制[亲测有效]

heap(堆)和stack(栈)

heap(堆)是用户主动请求而划分出来的内存区域,比如你new Object(),就是将一个对象存入堆中,可以理解为heap存对象。 stack(栈)是由于函数运行而临时占用的内存区域,函数都存放在栈里。

Event Loop实现过程

在上一张图中:

  1. 所有同步任务都在主线程上执行,形成一个执行栈;
  2. 只要异步任务有了运行结果,就在任务队列(task queue)(队列是一个先进先出的数据结构,而栈是一个先进后出的数据结构)之中放置一个事件;
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,又将队列中的事件放到stack中依次执行,就是执行异步任务中的回调函数。这个过程是循环不断的,这就是Event Loop(事件循环);

宏任务和微任务

在上张图中,我们看到还有宏任务(MacroTask)和微任务(MicroTask)之分。

宏任务(MacroTask) setTimeout setInterval

微任务(MicroTask) Promise.then MessageChannel微任务(vue中nextTick实现原理)

同步任务先执行,遇到微任务 就将微任务放入执行栈 微任务会先执行,再执行宏任务,

先看一下图(个人理解)

理解JS中的Event Loop机制[亲测有效]

举例说明

console.log(1);
setTimeout(function(){
    console.log(2);
    new Promise(function(resolve,reject){
        console.log('promise');
        resolve();
    }).then(res=>{
        console.log('promise.then');
    })
});
setTimeout(function(){
        console.log(4);
    })
console.log(5);

将这行代码放入浏览器控制台中

理解JS中的Event Loop机制[亲测有效]

分析一下:

  • 执行栈中同步任务先执行,先走console.log(1)和console.log(5);
  • 接着是遇到setTimeout将它们的回调函数放入MacroTask(宏任务队列);
  • 然后将任务队列中的回调函数依次放入主执行栈中执行:console.log(2)执行,接着promise立即执行,然后promise.then是微任务放入MicroTask中直接入栈先执行;
  • 最后执行第二个setTimeout的回调函数console.log(4);

Node.js的Event Loop

浏览器中的Event Loop和node的Event Loop有所不同,先来看看区别:

理解JS中的Event Loop机制[亲测有效]

在node环境里,执行栈会先执行完当前任务队列,也就是两个setTimeout中的回调函数执行完才会去执行我们的微任务队列,也就是promise.then是最后执行的,是不是很奇怪。

请看下面的示意图(作者 @BusyRich)。

理解JS中的Event Loop机制[亲测有效]

这里需要注意一下,node新加了一个微任务(process.nextTick)和一个宏任务(setImmediate)

简单的来说,就是node在处理一个执行队列的时候不管怎样都会先执行完当前队列,然后再清空微任务队列,再去执行下一个队列。

废话不多说,直接上图(个人理解)。

理解JS中的Event Loop机制[亲测有效]

这里应该都明白了吧,最后注意一下,微任务中process.nextTick比promise.then快

理解JS中的Event Loop机制[亲测有效]

水平不足,欢迎各位指正。

参考资料

JavaScript 运行机制详解:再谈Event Loop

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/13851.html

(0)

相关推荐

  • 如何使用Python备份PG数据库

    如何使用Python备份PG数据库PostgreSQL(简称 PG)是一个高度可扩展的关系型数据库管理系统。由于其可靠性和强大性,越来越多的开发者将其用于生产环境。但是即使是最可靠的系统,也难免出现故障,因此定期备份是非常重要的。本文将介绍如何使用Python备份PG数据库。

    2024-09-10
    26
  • 大话MySQL锁_大话西游加锁密码

    大话MySQL锁_大话西游加锁密码
    一、锁介绍 不同存储引擎支持的锁是不同的,比如MyISAM只有表锁,而InnoDB既支持表锁又支持行锁。 下图展示了InnoDB不同锁类型之间的关系: 图中…

    2023-04-05
    161
  • sql server cpu占用率高_sqlserver占用内存过大

    sql server cpu占用率高_sqlserver占用内存过大今天发现监控的一个SQL Server数据库实例的CPU有些异常,如下所示,系统消耗的CPU(O/S CPU Utilization)和数据库实例消耗的CPU(Instance CPU Utiliza

    2023-02-05
    151
  • Spark TempView和GlobalTempView的区别[通俗易懂]

    Spark TempView和GlobalTempView的区别[通俗易懂]Spark TempView和GlobalTempView的区别 TempView和GlobalTempView在spark的Dataframe中经常使用,两者的区别和应用场景有什么不同。 我们以下面

    2023-03-18
    153
  • Python字典——高效存储和访问数据

    Python字典——高效存储和访问数据Python字典是一种非常有用的数据类型,它可以用来存储任意对象,并且可以通过键来访问这些对象。字典是可变的,可以很方便地对其进行增、删、改等操作,非常适合用来存储和管理数据。

    2024-01-01
    116
  • 如何卸载Jupyter Notebook

    如何卸载Jupyter Notebook在使用 Jupyter Notebook 长时间后,我们可能会需要卸载它。卸载 Jupyter Notebook 的原因可能是因为你想更新 Jupyter Notebook 或者 你需要删除 Jupyter Notebook 以便重新安装它。不管是哪种情况,本文将会告诉你如何在 Windows,MacOS 和 Linux 上卸载 Jupyter Notebook。

    2024-07-26
    27
  • 如何在Linux中修改文件夹名称

    如何在Linux中修改文件夹名称在Linux系统中,修改文件夹名称是一个常见的操作。有时候,我们需要更改文件夹名称以使其更具有显著的性质或更方便查找。这篇文章将深入探讨如何在Linux中修改文件夹名称。

    2024-07-07
    49
  • Python Logo

    Python LogoPython是一种高级编程语言,具有简洁、优美、易读易写等特点,因此备受欢迎。Python语言的标志性符号是一个蓝色、黄色、红色的蟒蛇,被称为“Python Logo”。

    2024-05-08
    70

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注