JavaScript 中的并发与多线程:从入门到精通

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 中的并发与多线程:从入门到精通



JavaScript 历史上是一种单线程语言,运行在事件驱动编程范式下。然而,现代 JavaScript(尤其是在 Node.js 环境中)提供了强大的工具来处理并发和多线程。在本文中,我们将深入探讨 Event Loop、Promises、async/await、Worker Threads 和集群的工作原理,以及如何使用这些机制来提高应用程序的性能。



1. Event Loop:JavaScript 并发的基础



Event Loop 是 JavaScript 异步模型的核心。它允许在不阻塞主执行线程的情况下处理多个操作。在 Node.js 中,Event Loop 管理任务队列(宏任务和微任务),实现非阻塞 I/O。



Event Loop 工作示例:



console.log('开始');

setTimeout(() => { console.log('定时器 1');}, 0);

process.nextTick(() => { console.log('nextTick');});

Promise.resolve().then(() => { console.log('Promise');});

console.log('结束');

// 输出:// 开始// 结束// nextTick// Promise// 定时器 1


理解执行顺序很重要:同步代码 → 微任务(process.nextTick, Promise.then)→ 宏任务(setTimeout, setInterval)。



2. Promises 和 async/await:管理异步操作



Promises 是表示异步操作结果的对象。它们允许避免“回调地狱”并构建调用链。async/await 是 Promises 的语法糖,使异步代码看起来像同步代码。



使用 async/await 的示例:



const fetchData = async (url) => {  const response = await fetch(url);  if (!response.ok) {    throw new Error(`HTTP 错误:${response.status}`);  }  return await response.json();};

const main = async () => { try { const data = await fetchData('https://api.example.com/data'); console.log('获取的数据:', data); } catch (error) { console.error('错误:', error.message); }};

main();


这种方法允许使用 Promise.all() 并行执行多个异步操作:



const [user, posts] = await Promise.all([  fetchUser(userId),  fetchPosts(userId)]);console.log(user, posts);


3. Worker Threads:Node.js 中的真正多线程



从 Node.js 10.5.0 开始,worker_threads 模块提供了创建真正线程来执行 CPU 密集型任务的能力。每个 Worker 在独立的线程中运行,拥有自己的 V8 实例。



创建 Worker 的示例:



// main.jsconst { Worker } = require('worker_threads');

const runWorker = (workerData) => { return new Promise((resolve, reject) => { const worker = new Worker('./worker.js', { workerData });

worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) { reject(new Error(`Worker 以代码 ${code} 停止`)); } }); });};

const main = async () => { const result = await runWorker({ iterations: 1000000 }); console.log('结果:', result);};

main();


// worker.jsconst { parentPort, workerData } = require('worker_threads');

const heavyComputation = (iterations) => { let result = 0; for (let i = 0; i < iterations; i++) { result += Math.sqrt(i); } return result;};

const result = heavyComputation(workerData.iterations);parentPort.postMessage(result);


Worker Threads 非常适合会阻塞 Event Loop 的任务:图像处理、数学计算、解析大文件。



4. 集群:扩展到多个进程

\

博客

书籍推荐