JS核心-EventLoop的运作原理

目录

背景

Javascript的运行时环境

同步与异步

EventLoop运行机制

案例分析

延伸:宏任务和微任务

总结

参考链接



背景

Javascript的运行时环境

Javascript的运行时环境一般是指浏览器或者Node.js。 一般来说Javascript运行时环境除了用来解析和执行JS代码的Javascript引擎,还包括WebAPI,线程池,任务队列,EventLoop等等。这些组件组合起来后为Javascript提供一个异步响应式的环境。

同步与异步

同步:一次只能做一件事。Javacript引擎是一个单线程。负责解释和执行JavaScript代码这意味着一次只能做一件事。好比单行车道, 一次只能通过一辆车,故容易造成阻塞。

单线程只能做同步操作,那么如何解决阻塞带来的问题? 异步编程。Javascript运行时提供了一个EventLoop的事件循环模型,来处理异步操作。下面本人从EventLoop的结构和代码案例,两方面分析EventLoop工作原理。

EventLoop运行机制

概览:EventLoop在Javascript运行时(浏览器环境)的位置。

Call stack:函数调用栈。JS每次执行一行代码,

WebAPI:当调用栈遇到setTimeout(callback,timeout)API的时候,会交给浏览器的计时器倒计时,时间到达后,会把callback压入callBackQueue中。

CallbackQueue:callBackQueue用来保存回调函数

EventLoop:事件循环器周期性的检测调用栈是否为空,如果调用栈为空,则会把callbackQueue的回调出队,放入调用栈中执行。

RenderQueue: 渲染事件队列。EventLoop会优先调度渲染队列中的callback。

 调用栈的代码是在JS单线程中执行的。所以callback和调用栈如果执行时间过长,会导致页面渲染的过程被阻塞住。

GUI进程中的GUI渲染线程负责页面渲染,但是其同JS的单线程是互斥的,两者通过EventLoop通信。

案例分析

function pipe(){
 console.log('do easy sth... 1');
 setTimeout(function (){
        console.log("do hard sth... 2")
    }, 1000)
 setTimeout(function (){
        console.log("do hard sth... 3")
    }, 1000)
 setTimeout(function (){
        console.log("do hard sth... 4")
    }, 1000)
 setTimeout(function (){
        console.log("do hard sth... 5")
    }, 1000)
 setTimeout(function (){
        console.log("do hard sth... 6")
    }, 1000)
   
    console.log('do easy sth... 7')
}
//输出:1,7,2,3,4,5,6

上面代码输出为什么不是1,2,3,4,5,6,7? 这是因为,JS优先执行调用栈内的代码,所以1 ,7会先打印,其次setTimeout会把其callback放到Callback队列等待被EventLoop调度。而EventLoop只有等调用栈为空的时候,才会依次调度CallBack队列。所以我们要尽量保证UI渲染靠前执行,且调用栈不要做耗时操作。

延伸:宏任务和微任务

微任务:Promise每次调用then()时,注册的任务。

宏任务:callback队列或者调用栈中的每帧都是宏任务,宏任务执行完会立即执行当前微任务队列,之后才会切换到渲染线程执行页面渲染任务。

它们之间的关系:  宏任务->微任务->渲染任务-->宏任务...

总结

EventLoop是GUI编程中常见的异步编程的模型,Android开发中也有其身影。调用栈就像流水线,专门生产产品,遇到需要耗时操作的任务,就扔给产品打磨部门(WebAPI),产品打磨部门把耗时任务做完,任务结果,放入队列排队,交给EventLoop这个调度员调度,EventLoop监控流水线有空的时候就会轮训callback队列,把CallBack队列的耗时任务结果拿出来,交给流水线继续干活。

参考链接

从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理 - 掘金见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正。 ----------超长文+多图预警,需要花费不少时间。---------- 如果看完本文后,还对进程线程傻傻分不清,不清楚浏览器多进程、浏览器内核多线程、JS单线程、JS运行机制的区别。那么请回复我,一定是我…https://juejin.cn/post/6844903553795014663#heading-21

【自制熟肉】Philip Roberts:到底什么是Event Loop呢?(JSConf EU 2014)_哔哩哔哩_bilibili抽空翻译的演讲视频,讲的很棒,大家可以看一下https://www.bilibili.com/video/BV1oV411k7XY/

猜你喜欢

转载自blog.csdn.net/sannian1314/article/details/121572965