TypeScript中的并发与多线程:从理论到实践
现代Web应用程序越来越频繁地面临处理大量数据和执行资源密集型操作的需求,同时不能阻塞用户界面。TypeScript作为JavaScript的超集,继承了其单线程执行模型,但同时提供了强大的工具来组织并发和多线程。在本文中,我们将探讨如何在您的项目中有效利用这些功能。
理解并发与多线程
在深入代码之前,区分两个关键概念很重要:
- 并发 — 系统在重叠的时间段内处理多个任务的能力,但不一定同时进行。这是通过快速上下文切换实现的。
- 多线程 — 在CPU的不同核心上并行执行多个线程。在Node.js中,这是通过Worker Threads实现的。
TypeScript在Node.js环境中运行,主线程通过Event Loop处理事件。对于繁重的计算,这可能会成为瓶颈。
异步和Promise:并发的基础
TypeScript中并发的底层构建于async/await和Promise之上。这些机制允许在等待I/O操作期间不阻塞主线程。
// 异步加载数据示例interface User { id: number; name: string;}
async function fetchUser(id: number): Promise<User> { const response = await fetch(`https://api.example.com/users/${id}`); return response.json();}
// 并行启动多个请求async function loadUsers(): Promise<User[]> { const userIds = [1, 2, 3, 4, 5]; const promises = userIds.map(id => fetchUser(id)); return Promise.all(promises);}
loadUsers().then(users => { console.log('已加载用户数:', users.length);});Promise.all同时启动所有promise,但它们在同一线程中执行。这对于I/O任务来说是理想的,但不适用于CPU密集型操作。
Worker Threads:真正的多线程
要在不阻塞主线程的情况下执行繁重计算,请使用Worker Threads。这是Node.js的内置模块,它创建具有自己内存的独立线程。
让我们创建一个在单独线程中计算斐波那契数列的示例:
// fibonacci.worker.tsimport { parentPort } from 'worker_threads';
function fibonacci(n: number): number { if (n <= 1) return n; return fibonacci(n - 1) + fibonacci(n - 2);}
parentPort?.on('message', (n: number) => { const result = fibonacci(n); parentPort?.postMessage(result);});// main.tsimport { Worker } from 'worker_threads';import path from 'path';
function runFibonacciInWorker(n: number): Promise<number> { return new Promise((resolve, reject) => { const worker = new Worker(path.resolve(__dirname, 'fibonacci.worker.ts')); worker.postMessage(n); worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(`Worker stopped with exit code ${code}`)); }); });}
async function main() { console.time('fibonacci'); const result = await runFibonacciInWorker(40); console.timeEnd('fibonacci'); console.log(`Fibonacci(40) = ${result}`);}
main();请注意:要运行TypeScript worker,需要编译成JavaScript。可以使用ts-node或预先编译。
SharedArrayBuffer:线程间的共享内存
当线程需要交换大量数据时