资讯专栏INFORMATION COLUMN

理解JS中的Event Loop机制

MASAILA / 1042人阅读

摘要:前言前几天在理解的事件环机制中引发了我对浏览器里的好奇。接下来理解浏览器中的,先看一张图堆和栈堆是用户主动请求而划分出来的内存区域,比如你,就是将一个对象存入堆中,可以理解为存对象。废话不多说,直接上图个人理解。参考资料运行机制详解再谈

前言

前几天在理解node的事件环机制中引发了我对浏览器里Event Loop的好奇。我们都知道javascript是单线程的,任务是需要一个一个按顺序执行的,如果javascript有两个线程,一个为DOM增加样式,一个却要删除DOM,这样岂不是就会很混乱。单线程可以节约内存,但是必须等待前一个任务完成后才能执行下一个任务。接下来理解浏览器中的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实现原理)
同步任务先执行,遇到微任务 就将微任务放入执行栈 微任务会先执行,再执行宏任务,

先看一下图(个人理解)

举例说明
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);

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

分析一下:
执行栈中同步任务先执行,先走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有所不同,先来看看区别:

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

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

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

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

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

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

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

参考资料

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

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

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

相关文章

  • 10分钟理解JS引擎的执行机制

    摘要:深入理解引擎的执行机制灵魂三问为什么是单线程的为什么需要异步单线程又是如何实现异步的呢中的中的说说首先请牢记点是单线程语言的是的执行机制。 深入理解JS引擎的执行机制 1.灵魂三问 : JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.说说setTimeout 首先,请牢记2...

    zzbo 评论0 收藏0
  • 深入理解js引擎的执行机制

    摘要:深入理解引擎的执行机制最近在反省,很多知识都是只会用,不理解底层的知识。在阅读之前,请先记住两点是单线程语言的是的执行机制。所以,是存在异步执行的,比如单线程是怎么实现异步的场景描述通过事件循环,所以说,理解了机制,也就理解了的执行机制啦。 深入理解js引擎的执行机制 最近在反省,很多知识都是只会用,不理解底层的知识。所以在开发过程中遇到一些奇怪的比较难解决的bug,在思考的时候就会收...

    feng409 评论0 收藏0
  • JavaScript执行机制、事件循环

    摘要:曾经的理解首先,是单线程语言,也就意味着同一个时间只能做一件事,那么为什么不是多线程呢这样还能提高效率啊假定同时有两个线程,一个线程在某个节点上编辑了内容,而另一个线程删除了这个节点,这时浏览器就很懵逼了,到底以执行哪个操作呢所以,设计者把 Event Loop曾经的理解 首先,JS是单线程语言,也就意味着同一个时间只能做一件事,那么 为什么JavaScript不是多线程呢?这样还能提...

    rose 评论0 收藏0
  • 初窥JavaScript事件机制的实现(一)—— Node.js事件驱动实现概览

    摘要:如果当前没有事件也没有定时器事件,则返回。相关资料关于的架构及设计思路的事件讨论了使用线程池异步运行代码。下一篇初窥事件机制的实现二中定时器的实现 在浏览器中,事件作为一个极为重要的机制,给予JavaScript响应用户操作与DOM变化的能力;在Node.js中,事件驱动模型则是其高并发能力的基础。 学习JavaScript也需要了解它的运行平台,为了更好的理解JavaScript的事...

    lavor 评论0 收藏0
  • 【转】深入理解JS单线程机制【原文作者:MasterYao】

    摘要:的单线程,与它的用途有关。只要指定过回调函数,这些事件发生时就会进入任务队列,等待主线程读取。四主线程从任务队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为事件循环。令人困惑的是,文档中称,指定的回调函数,总是排在前面。 原文:http://www.cnblogs.com/Master... 一、为什么JavaScript是单线程? JavaScript语言的一大特点...

    LittleLiByte 评论0 收藏0

发表评论

0条评论

MASAILA

|高级讲师

TA的文章

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