🍉如何理解单线程的JavaScript及其工作原理|8月更文挑战

简介: 🍉如何理解单线程的JavaScript及其工作原理|8月更文挑战

随着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及其它。它们怎么执行呢,实际情况有点复杂。


image.png


于是乎,就有了如此流行的事件循环(也称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函数。就会出现如下情况:


image.png


当调用栈中的函数调用次数超过了调用栈的实际大小,浏览器决定抛出一个错误,如下图所示:


image.png


小伙伴们可以自己在浏览器的控制台里试试!


六、事件循环(Event Loop)


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


image.png


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


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


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


最后


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

相关文章
|
3月前
|
存储 缓存 监控
什么是线程池?它的工作原理?
我是小假 期待与你的下一次相遇 ~
277 1
|
5月前
|
数据采集 消息中间件 并行计算
Python多线程与多进程性能对比:从原理到实战的深度解析
在Python编程中,多线程与多进程是提升并发性能的关键手段。本文通过实验数据、代码示例和通俗比喻,深入解析两者在不同任务类型下的性能表现,帮助开发者科学选择并发策略,优化程序效率。
466 1
|
7月前
|
机器学习/深度学习 JavaScript 前端开发
JS进阶教程:递归函数原理与篇例解析
通过对这些代码示例的学习,我们已经了解了递归的原理以及递归在JS中的应用方法。递归虽然有着理论升华,但弄清它的核心思想并不难。举个随手可见的例子,火影鸣人做的影分身,你看到的都是同一个鸣人,但他们的行为却能在全局产生影响,这不就是递归吗?雾里看花,透过其间你或许已经深入了递归的魅力之中。
328 19
|
自然语言处理 JavaScript 前端开发
深入理解JavaScript中的闭包:原理与实战
【10月更文挑战第12天】深入理解JavaScript中的闭包:原理与实战
|
7月前
|
数据采集 网络协议 前端开发
Python多线程爬虫模板:从原理到实战的完整指南
多线程爬虫通过并发请求大幅提升数据采集效率,适用于大规模网页抓取。本文详解其原理与实现,涵盖任务队列、线程池、会话保持、异常处理、反爬对抗等核心技术,并提供可扩展的Python模板代码,助力高效稳定的数据采集实践。
384 0
|
10月前
|
JavaScript 前端开发 Java
深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解
Array.find() 是 JavaScript 数组方法中一个非常实用和强大的工具。它不仅提供了简洁的查找操作,还具有性能上的独特优势:返回的引用能够直接影响原数组的数据内容,使得数据更新更加高效。通过各种场景的展示,我们可以看到 Array.find() 在更新、条件查找和嵌套结构查找等场景中的广泛应用。 在实际开发中,掌握 Array.find() 的特性和使用技巧,可以让代码更加简洁高效,特别是在需要直接修改原数据内容的情形。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
10月前
|
监控 JavaScript 前端开发
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
MutationObserver 是一个非常强大的 API,提供了一种高效、灵活的方式来监听和响应 DOM 变化。它解决了传统 DOM 事件监听器的诸多局限性,通过异步、批量的方式处理 DOM 变化,大大提高了性能和效率。在实际开发中,合理使用 MutationObserver 可以帮助我们更好地控制 DOM 操作,提高代码的健壮性和可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例
|
11月前
|
安全 Java 开发者
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
10月前
|
JavaScript 前端开发 Java
详解js柯里化原理及用法,探究柯里化在Redux Selector 的场景模拟、构建复杂的数据流管道、优化深度嵌套函数中的精妙应用
柯里化是一种强大的函数式编程技术,它通过将函数分解为单参数形式,实现了灵活性与可复用性的统一。无论是参数复用、延迟执行,还是函数组合,柯里化都为现代编程提供了极大的便利。 从 Redux 的选择器优化到复杂的数据流处理,再到深度嵌套的函数优化,柯里化在实际开发中展现出了非凡的价值。如果你希望编写更简洁、更优雅的代码,柯里化无疑是一个值得深入学习和实践的工具。从简单的实现到复杂的应用,希望这篇博客能为你揭开柯里化的奥秘,助力你的开发之旅! 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一
|
Java Linux 调度
硬核揭秘:线程与进程的底层原理,面试高分必备!
嘿,大家好!我是小米,29岁的技术爱好者。今天来聊聊线程和进程的区别。进程是操作系统中运行的程序实例,有独立内存空间;线程是进程内的最小执行单元,共享内存。创建进程开销大但更安全,线程轻量高效但易引发数据竞争。面试时可强调:进程是资源分配单位,线程是CPU调度单位。根据不同场景选择合适的并发模型,如高并发用线程池。希望这篇文章能帮你更好地理解并回答面试中的相关问题,祝你早日拿下心仪的offer!
325 6