【Web技术】1055- 如何理解单线程的JavaScript及其工作原理

随着JavaScript的日益流行,团队也利用其在前端,后端,混合APPS,嵌入式设备以及更多设备等开发栈中诸多层面的支持,JavaScript能创造出令人惊叹的软件,开发就必须更加深入了解JavaScript语言的内部工作机制!

此篇文章会详细地研究并解释JavaScript的工作原理,通过了解这些细节,通过合理地使用提供的APIs,你将能够写出更好的,非阻塞的程序。

一、单线程的来源

几乎所有人都已经听过V8引擎的概念,并且很多人知道JavaScript是单线程的,JavaScript作为浏览器脚本语言,它的主要用途是与用户交互,那么为什么JavaScript是单线程呢?如果JavaScript是多线程,当页面更新内容的时候、用户又触发了交互,这时候线程间的同步问题会变得很复杂,为了避免复杂性,故JavaScript被设计成单线程。

二、JavaScript引擎

谷歌V8引擎是一个流行的JavaScript引擎。这里有一个简单的视图来描绘其大概模样。

image.png

引擎包括两个组件:

  • 内存堆——进行内存分配的区域
  • 调用栈——代码执行时栈中的位置

三、运行时

几乎每个JavaScript开发者都使用过一些浏览器 API(比如setTimeout)。然而这些API并不是引擎所提供的。这些Web API是浏览器提供的,还有DOM事件,AJAX及其它。它们怎么执行呢,实际情况有点复杂。

于是乎,就有了如此流行的事件循环(也称event loop或事件轮询)和回调队列。

四、调用栈

前面我们说过,JavaScript是单线程的编程语言,这意味着只有一个调用栈。这样它只能一次做一件事情。调用栈是一种数据结构。当执行进入一个函数,把它置于栈的底部。如果从函数中返回则从栈底部移除函数。这就是调用栈所做的事情。
举个🌰子,看如下代码:

fucntion multiply(x,y) {
    return x * y;
}
function printSquare(x{
    var s = mulitiply(x,x);
    console.log(s);
}
printSquare(s);

当引擎开始执行这段代码的时候,调用栈会被清空,之后产生如下步骤:

image.png

五、堆栈溢出

一旦达到最大调用栈大小的时候发生。这种情况相当容易发生。特别是当你使用递归时,看下面的代码:

function foo () {
    foo();
}
foo();

当引擎开始执行这段代码的时候,它开始调用foo函数。这个函数,然而会递归并开始调用其自身而没有任何结束条件。所以在每步执行过程中,调用堆栈会反复添加foo函数。就会出现如下情况:

当调用栈中的函数调用次数超过了调用栈的实际大小,浏览器决定抛出一个错误,如下图所示:
小伙伴们可以自己在浏览器的控制台里试试!

六、事件循环(Event Loop)

又该拿出那张经典的图了~

image.png

Event Loop 负责执行代码、收集和处理事件以及执行队列中的子任务。

具体包括:

  • Javascript 有一个主线程和执行栈,所有的任务都会被放到调用栈等待主线程执行
  • 同步任务会被放在调用栈中,按照顺序等待主线程依次执行
  • 主线程之外存在一个任务队列,所有任务在主线程中以执行栈的方式运行
  • 同步任务都在主线程上执行,栈中代码在执行的时候会调用 Web API,此时会产生一些异步任务
  • 异步任务会在有了结果(比如被监听的事件发生时)后,将注册的回调函数放入任务队列中
  • 执行栈中任务执行完毕后,此时主线程处于空闲状态,会从任务队列中获取任务进行处理

以上过程会不断重复,这就是浏览器的运行机制,也是Event Loop。

最后

Event Loop 我们还得继续,理解它是突破前端第一层天花板的毕竟之路!


关于本文

来源:_啊呜

https://juejin.cn/post/6991241111167565860

1. JavaScript 重温系列(22篇全)
2. ECMAScript 重温系列(10篇全)
3. JavaScript设计模式 重温系列(9篇全)
4.  正则 / 框架 / 算法等 重温系列(16篇全)
5.  Webpack4 入门(上) ||  Webpack4 入门(下)
6.  MobX 入门(上)  ||   MobX 入门(下)
7. 120 +篇原创系列汇总

回复“加群”与大佬们一起交流学习~

点击“阅读原文”查看 130+ 篇原创文章

本文分享自微信公众号 - 前端自习课(FE-study)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章