搜索
首页web前端js教程在 Javascript 中利用多线程 - 不是关于 WebWorkers 也不是 WebAssembly

Utilize Multi-Thread in Javascript - Not About WebWorkers nor 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 WorkersWebAssembly 实现真正的多线程操作。这些允许您在后台线程中运行脚本。它们无法直接操作 DOM,但对于处理繁重的任务(矩阵计算,有人吗?)来说它们非常宝贵。这种方法经常用于基于 HTML5 的游戏 - 更复杂的游戏,而不仅仅是井字游戏。

最后的话

JavaScript 在隔离时仍然是单线程的。但在现实世界中,它是一种在网络浏览器的多线程环境中运行的解释语言。如果您的口译员向您提供帮助,请接受并使用它。

这篇文章涵盖了很多内容——基础知识、底层解释等等。但这通常就是发展的方式——一切都是相互关联的。这就是为什么我喜欢看更广阔的前景。有时,专注细节并不能解决问题。


异步曾经给你带来过调试噩梦吗?
我当然有 - 几年前,获得有错误的堆栈并不是什么大事。

以上是在 Javascript 中利用多线程 - 不是关于 WebWorkers 也不是 WebAssembly的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
Python vs. JavaScript:您应该学到哪种语言?Python vs. JavaScript:您应该学到哪种语言?May 03, 2025 am 12:10 AM

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架:为现代网络开发提供动力JavaScript框架:为现代网络开发提供动力May 02, 2025 am 12:04 AM

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

JavaScript,C和浏览器之间的关系JavaScript,C和浏览器之间的关系May 01, 2025 am 12:06 AM

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

node.js流带打字稿node.js流带打字稿Apr 30, 2025 am 08:22 AM

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python vs. JavaScript:性能和效率注意事项Python vs. JavaScript:性能和效率注意事项Apr 30, 2025 am 12:08 AM

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。

JavaScript的起源:探索其实施语言JavaScript的起源:探索其实施语言Apr 29, 2025 am 12:51 AM

JavaScript起源于1995年,由布兰登·艾克创造,实现语言为C语言。1.C语言为JavaScript提供了高性能和系统级编程能力。2.JavaScript的内存管理和性能优化依赖于C语言。3.C语言的跨平台特性帮助JavaScript在不同操作系统上高效运行。

幕后:什么语言能力JavaScript?幕后:什么语言能力JavaScript?Apr 28, 2025 am 12:01 AM

JavaScript在浏览器和Node.js环境中运行,依赖JavaScript引擎解析和执行代码。1)解析阶段生成抽象语法树(AST);2)编译阶段将AST转换为字节码或机器码;3)执行阶段执行编译后的代码。

Python和JavaScript的未来:趋势和预测Python和JavaScript的未来:趋势和预测Apr 27, 2025 am 12:21 AM

Python和JavaScript的未来趋势包括:1.Python将巩固在科学计算和AI领域的地位,2.JavaScript将推动Web技术发展,3.跨平台开发将成为热门,4.性能优化将是重点。两者都将继续在各自领域扩展应用场景,并在性能上有更多突破。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

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

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),