本章内容
Atomics 与SharedArrayBuffer
跨上下文消息
Encoding API
File API 与Blob API
拖放
Notifications API
Page Visibility API
Streams API
计时API
Web 组件
Web Cryptography API
随着Web 浏览器能力的增加,其复杂性也在迅速增加。从很多方面看,现代Web 浏览器已经成为
构建于诸多规范之上、集不同API 于一身的“瑞士军刀”。浏览器规范的生态在某种程度上是混乱而无
序的。一些规范如HTML5,定义了一批增强已有标准的API 和浏览器特性。而另一些规范如Web
Cryptography API 和Notifications API,只为一个特性定义了一个API。不同浏览器实现这些新API 的情
况也不同,有的会实现其中一部分,有的则干脆尚未实现。
最终,是否使用这些比较新的API 还要看项目是支持更多浏览器,还是要采用更多现代特性。有些
API 可以通过腻子脚本来模拟,但腻子脚本通常会带来性能问题,此外也会增加网站JavaScript 代码的
体积。
Atomics 与SharedArrayBuffer
多个上下文访问SharedArrayBuffer 时,如果同时对缓冲区执行操作,就可能出现资源争用问
题。Atomics API 通过强制同一时刻只能对缓冲区执行一个操作,可以让多个上下文安全地读写一个
SharedArrayBuffer。Atomics API 是ES2017 中定义的。
仔细研究会发现Atomics API 非常像一个简化版的指令集架构(ISA),这并非意外。原子操作的本质会排斥操作系统或计算机硬件通常会自动执行的优化(比如指令重新排序)。原子操作也让并发访问
内存变得不可能,如果应用不当就可能导致程序执行变慢。为此,Atomics API 的设计初衷是在最少但
很稳定的原子行为基础之上,构建复杂的多线程JavaScript 程序。
SharedArrayBuffer
SharedArrayBuffer 与ArrayBuffer 具有同样的API。二者的主要区别是ArrayBuffer 必须
在不同执行上下文间切换,SharedArrayBuffer 则可以被任意多个执行上下文同时使用。
在多个执行上下文间共享内存意味着并发线程操作成为了可能。传统JavaScript 操作对于并发内存
访问导致的资源争用没有提供保护。下面的例子演示了4 个专用工作线程访问同一个
SharedArrayBuffer 导致的资源争用问题:
const workerScript = self.onmessage = ({data}) => { const view = new Uint32Array(data); // 执行1 000 000 次加操作 for (let i = 0; i < 1E6; ++i) { // 线程不安全加操作会导致资源争用 view[0] += 1; } self.postMessage(null); };
;
const workerScriptBlobUrl = URL.createObjectURL(new Blob([workerScript]));
// 创建容量为4 的工作线程池
const workers = [];
for (let i = 0; i < 4; ++i) {
workers.push(new Worker(workerScriptBlobUrl));
}
// 在最后一个工作线程完成后打印出最终值
let responseCount = 0;
for (const worker of workers) {
worker.onmessage = () => {
if (++responseCount == workers.length) {
console.log(Final buffer value: ${view[0]}
);
}
};
}
// 初始化SharedArrayBuffer
const sharedArrayBuffer = new SharedArrayBuffer(4);
const view = new Uint32Array(sharedArrayBuffer);
view[0] = 1;
// 把SharedArrayBuffer 发送到每个工作线程
for (const worker of workers) {
worker.postMessage(sharedArrayBuffer);
}
//(期待结果为4000001。实际输出可能类似这样:)
// Final buffer value: 2145106
为解决这个问题,Atomics API 应运而生。Atomics API 可以保证SharedArrayBuffer 上的
JavaScript 操作是线程安全的。
javascript基础从小白到高手系列一千九百八十一:JavaScript API
最新推荐文章于 2024-11-10 15:10:09 发布