在 Javascript 中利用多线程 - 不是关于 WebWorkers 也不是 WebAssembly
众所周知,JavaScript 在单线程上运行。这个概念是如此不可或缺,以至于我们经常用名称来引用它 - 主线程。那么,这是否意味着你的多核 CPU 在运行 JavaScript 时毫无用处?
不完全是。
JavaScript 可能有点厚颜无耻,发送有关其线程的混合消息。
但即使不深入研究 Web Workers 和 WebAssembly 等更复杂的功能,基本的 JavaScript 也可以利用多线程工作流程。
需要明确的是,本文重点介绍基于 Web 浏览器的 JavaScript。其他环境(例如 Node.js)可能会以不同的方式处理事情。
我们将探索 JavaScript 中多线程和类多线程操作的选项。现实是 - 您可以而且应该在基本的、纯原生 JavaScript 中使用多线程工作流程。
“解释!”
很高兴。
JavaScript 是一种单线程语言,但它由网络浏览器解释 - 而浏览器是多线程软件。
有多种方法可以模拟和利用多线程,您可能在没有意识到的情况下使用它们。
此外,JavaScript 的行为方式通常看起来是多线程的,但实际上并非如此。这听起来像是作弊,但它有效地提供了我们期望从多线程行为中获得的好处。
基于事件的编程感觉是多线程的
JavaScript 是一个基于事件的系统。当浏览器处理 JavaScript 文件时,它会运行其中的所有代码。完全有可能编写不停止运行的代码 - 尽管这通常是一个坏主意,因为它可能会导致浏览器崩溃。
我们通常做的就是设置事件监听器并等待事件发生。此时,JavaScript 完全空闲。如果不从主线程卸载一些工作,这种空闲等待是不可能的。
事件本身不是多线程的,但事件的等待和检查是由浏览器处理的,而不是由 JavaScript 处理。此进程从主线程卸载。
异步函数和多线程
像 setTimeout 和 setInterval 这样的函数已经陪伴我们很多年了。他们减轻了主线程的等待时间。
让我们简化一下它的工作原理。在较低级语言中,计时器和等待通常是通过不断检查“时间到了吗?”来实现的。想象一下 while() 循环检查经过的时间并在时间正确时继续执行。现代方法可能会使用 CPU 中断来避免阻塞 CPU 线程。
但是,当您在 JavaScript 中使用 setTimeout 或 setInterval 时,语言在等待期间完全空闲,这再次意味着等待以某种方式在主线程之外进行处理。
Fetch 和其他异步 API
如今,我们从浏览器获得越来越多的异步函数和 API。 fetch API 是一个众所周知的例子。即使是较新的 API,例如剪贴板 API,也是异步的。
这意味着您要求浏览器执行一个操作,它会释放 JavaScript 的主线程(或允许它处理其他内容 - 稍后会详细介绍)并在完成时通知您(通过处理以下代码)。
异步与多线程
异步并不一定意味着多线程——并不总是、不直接。简单地将“async”这个词放在函数前面对你来说没有任何作用。
JavaScript 如何处理异步行为有两个关键组件:
1. 回调队列和事件循环
将回调队列视为一行等待运行的函数。这些函数在主线程中一一执行。当异步操作完成时 - 无论是事件、超时还是已完成的获取 - 其回调都会放置在此队列中。
事件循环负责当调用堆栈为空时将回调从队列移动到调用堆栈。
2. 浏览器处理的函数
网络浏览器控制某些操作,并可能为它们启动新线程 - 这包括 fetch 或 setTimeout 等操作。 JavaScript 不需要管理这些线程。当异步操作完成后,浏览器将相应的回调放入回调队列中,JavaScript 从那里继续执行。
考虑这段代码:
console.log('Start'); setTimeout(() => { console.log('This is asynchronous'); }); console.log('End');
输出:
Start End This is asynchronous
发生的事情是这样的:
- “开始”已记录。
- setTimeout 调用时没有超时参数,因此默认为 0 毫秒。当前调用堆栈清空后,回调将发送到浏览器执行。
- “结束”已记录。
- 主线程现在空闲,事件循环检查回调队列。
- setTimeout 的回调函数被移至调用堆栈。
- 记录“这是异步的”。
注意 setTimeout 缺少超时参数。这是推迟低优先级代码执行的常见技术 - 首先处理所有其他内容,完成后,执行“较低优先级”的事情。
它的作用是立即将 setTimeout 内的函数放入回调队列中,并在主线程空闲时第一时间运行。
requestAnimationFrame 的特例
requestAnimationFrame 是一个浏览器 API,它告诉浏览器您想要在计算和更新视图之前执行一些代码(将其视为视频游戏中的每秒帧数)。
出于某种原因,Web 开发人员不会考虑重绘和 FPS,但这就是它的工作原理。
它本质上是异步的(尽管不是多线程)。
在引入 requestAnimationFrame 之前,使用不指定时间的 setTimeout 经常用于类似的目的,尽管它远没有那么有用(只是聊胜于无)。
此函数将您的代码排队到一个特殊的堆栈中。就在渲染新帧(重绘)之前,浏览器运行此排队的代码。它非常适合对 DOM、HTML 或 CSS 进行更改(只有那些,请,我禁止您在那里进行计算!)。
真正的多线程选项
虽然本文与它们无关,但值得一提的是,您可以通过利用 Web Workers 和 WebAssembly 实现真正的多线程操作。这些允许您在后台线程中运行脚本。它们无法直接操作 DOM,但对于处理繁重的任务(矩阵计算,有人吗?)来说它们非常宝贵。这种方法经常用于基于 HTML5 的游戏 - 更复杂的游戏,而不仅仅是井字游戏。
最后的话
JavaScript 在隔离时仍然是单线程的。但在现实世界中,它是一种在网络浏览器的多线程环境中运行的解释语言。如果您的口译员向您提供帮助,请接受并使用它。
这篇文章涵盖了很多内容——基础知识、底层解释等等。但这通常就是发展的方式——一切都是相互关联的。这就是为什么我喜欢看更广阔的前景。有时,专注细节并不能解决问题。
异步曾经给你带来过调试噩梦吗?
我当然有 - 几年前,获得有错误的堆栈并不是什么大事。
以上是在 Javascript 中利用多线程 - 不是关于 WebWorkers 也不是 WebAssembly的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

JavaScript是现代Web开发的基石,它的主要功能包括事件驱动编程、动态内容生成和异步编程。1)事件驱动编程允许网页根据用户操作动态变化。2)动态内容生成使得页面内容可以根据条件调整。3)异步编程确保用户界面不被阻塞。JavaScript广泛应用于网页交互、单页面应用和服务器端开发,极大地提升了用户体验和跨平台开发的灵活性。

JavaScript的最新趋势包括TypeScript的崛起、现代框架和库的流行以及WebAssembly的应用。未来前景涵盖更强大的类型系统、服务器端JavaScript的发展、人工智能和机器学习的扩展以及物联网和边缘计算的潜力。

不同JavaScript引擎在解析和执行JavaScript代码时,效果会有所不同,因为每个引擎的实现原理和优化策略各有差异。1.词法分析:将源码转换为词法单元。2.语法分析:生成抽象语法树。3.优化和编译:通过JIT编译器生成机器码。4.执行:运行机器码。V8引擎通过即时编译和隐藏类优化,SpiderMonkey使用类型推断系统,导致在相同代码上的性能表现不同。

JavaScript是现代Web开发的核心语言,因其多样性和灵活性而广泛应用。1)前端开发:通过DOM操作和现代框架(如React、Vue.js、Angular)构建动态网页和单页面应用。2)服务器端开发:Node.js利用非阻塞I/O模型处理高并发和实时应用。3)移动和桌面应用开发:通过ReactNative和Electron实现跨平台开发,提高开发效率。

Python更适合初学者,学习曲线平缓,语法简洁;JavaScript适合前端开发,学习曲线较陡,语法灵活。1.Python语法直观,适用于数据科学和后端开发。2.JavaScript灵活,广泛用于前端和服务器端编程。

本文展示了与许可证确保的后端的前端集成,并使用Next.js构建功能性Edtech SaaS应用程序。 前端获取用户权限以控制UI的可见性并确保API要求遵守角色库

从C/C 转向JavaScript需要适应动态类型、垃圾回收和异步编程等特点。1)C/C 是静态类型语言,需手动管理内存,而JavaScript是动态类型,垃圾回收自动处理。2)C/C 需编译成机器码,JavaScript则为解释型语言。3)JavaScript引入闭包、原型链和Promise等概念,增强了灵活性和异步编程能力。

我使用您的日常技术工具构建了功能性的多租户SaaS应用程序(一个Edtech应用程序),您可以做同样的事情。 首先,什么是多租户SaaS应用程序? 多租户SaaS应用程序可让您从唱歌中为多个客户提供服务
