众所周知,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中文网其他相关文章!

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

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

Atom编辑器mac版下载
最流行的的开源编辑器

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