事件循环解析-带你搞懂JS底层代码运行机制

目录

        单线程

        同步和异步

        执行过程


        前言: 为什么要了解事件循环(evemtloop)呢?这样可以让我们对底层的代码运行机制有一个更清晰的认知了解,扎实我们的基本功。明白了事件循环后,于我们而言对后续的同步异步、Promise、Vue的$nextTick等等的学习都会有很好的理解与帮助。

单线程

        在说事件循环之前,我们要先知道,javascript不同于其他的多线程语言。javascript是单线程的,也就是说同一个时间内呢,它只能做一件事,这与javascript本身的特性有关,因为js是浏览器脚本语言,它更多的是要需要用户进行交互、还有操作DOM等等。这些便决定了它只能单线程。

        比如以下有两个线程

线 程 1 -- 添 加 节 点  DOM 1线 程 2 -- 删 除 节 点  DOM 1

        如果去执行的话,很明显这两个不能同时执行,肯定等到添加完 DOM1 后才能去删除,所以这也是js的语言特点所在。因此它的执行顺序应该是以下这种。

线 程 1添 加 节 点  DOM 1
线 程 2删 除 节 点  DOM 1

         当然,这样的单线程也是会引起一些问题的

         比如以下情况 :

        
     

         有些任务是耗时的,亦或者有些任务需要执行某些事件执行后才能去执行,那么这样就会阻塞了代码执行,这样去等着肯定是有问题的。

同步和异步

        有问题就需要去解决。所以js便引出了同步和异步的概念。这时在同步代码和异步代码之间就会有鲜明的执行顺序了。

        什么是同步和异步呢?

        同步就是后一个任务等待前一个任务执行完成后,再执行,执行顺序和任务的排序顺序一样

        异步是非阻塞的,异步逻辑与主逻辑相互独立,主逻辑不需要等待异步逻辑完成,而是阔以直接执行下去

        同步代码有:

                比如 console.log( “ Hello Word” ) 这种的就属于立即执行的同步代码

       异步代码有:

                setInterval(定时器)

                setTimeout(一次性定时器)

                AJAX/Fetch

                事件绑定

                promise实例的.then方法( Promise本身是同步的 )

       可以发现,异步代码有一个共同点,那就是比较耗时。

      在 JS 中,异步任务还会分为宏任务和微任务。

        因为在ES5之后,JS又引入了Promise。这样,promise不需要浏览器,JS引擎 自身可以发起异步任务了。

所以在执行过程中,我们还可以把JS代码分为三类

        1. 同步代码(JS执行栈 / 回调栈)

        2. 微任务的异步代码(JS引擎)

                process.nextTick( node )

                Promise.then( ).catch( ) 

                Async/Await

                Object.observe等等

        3. 宏任务中的异步代码 (宿主环境)

                Script( 整个代码块 ) 

                setInterval/setTimeout 定时器

执行过程

        先给大家说一个适合比较直观的可以练习和理解事件循环的网站

                    点击进入   : JS Visualizer 9000

        那么事件循环究竟是怎样的一个过程呢?

        废话不多说,看图:

        

        js在解析代码时,当遇到同步代码,会立即放进 JS引擎(主线程) 中执行,并且原地等待结果。遇到异步代码时,会先放入 宿主环境(浏览器/Node) ,因为JS引擎是无法处理异步的,它会放到浏览器或者node去处理, 不需要原地等待结果,不会阻塞主线程向下执行代码,异步结果会在将来执行。当正确的时机到来后(比如定时器时间到了),宿主环境会把里面的异步代码的回调函数推送到一个任务队列(此时会分为宏任务和微任务队列,优先执行微任务队列里的异步任务),所以异步任务其实是会推到一个任务队列中来排队的,因为可能会有多个不同执行时间的异步任务。如果是一个点击事件,会在点击完成后才会将宿主环境中的回调函数推到任务队列中。这个时候,如果执行栈中的同步任务全部执行完成后,就会来到任务队列中查看是否有异步任务,有就推送到执行栈中去执行,执行完后再到任务队列中看有没有异步任务,有的话就再推过去执行,来来回回反复的过程我们称为事件循环。

        下面阔以看下简洁版的

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值