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

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

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

开始课程

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

在现代Web开发世界中,应用程序性能已成为首要关注点。TypeScript作为JavaScript的强类型超集,为开发者提供了处理异步和多线程的强大工具。在本文中,我们将深入探讨并发的基本概念,了解事件循环的工作原理,并学习如何在Node.js中使用Worker Threads实现真正的多线程。



1. 异步与事件循环:TypeScript中并发的基础

在讨论多线程之前,理解TypeScript(以及JavaScript)如何处理并发任务至关重要。其核心是事件循环——一种机制,允许执行非阻塞的输入/输出操作,而无需创建新线程。

来看一个简单的异步代码示例:

async function fetchData(url: string): Promise<string> {    const response = await fetch(url);    return response.text();}

async function main(): Promise<void> { console.log('开始加载'); const data = await fetchData('https://api.example.com/data'); console.log('数据已获取:', data);}

main();console.log('代码继续执行');

在这个示例中,await不会阻塞主线程。在等待服务器响应期间,事件循环继续处理其他任务,例如执行console.log。这就是并发——在同一个时间段内处理多个任务的能力,通过在任务之间切换来实现。



2. Promise与async/await:管理异步操作

TypeScript提供了方便的语法结构来处理异步操作。Promise是表示异步操作未来结果的对象。async/await的组合使代码变得线性且可读。

来看一个更复杂的场景——并行执行多个请求:

async function loadMultipleUsers(userIds: number[]): Promise<User[]> {    const promises = userIds.map(id => fetch(`/users/${id}`).then(res => res.json()));    return Promise.all(promises);}

// 使用const users = await loadMultipleUsers([1, 2, 3, 4, 5]);console.log(users); // 所有用户已并行加载

Promise.all方法同时启动所有Promise,与顺序加载相比显著加快了执行速度。这是并发的理想示例:任务在单个线程内“同时”执行。



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

虽然异步在处理输入/输出操作方面表现出色,但它对CPU密集型任务(如图像处理、复杂计算、加密)无能为力。对于这种情况,Node.js提供了Worker Threads——真正的操作系统线程。

来看一个在单独线程中计算阶乘的示例:

// worker.tsimport { parentPort } from 'worker_threads';

function factorial(n: number): number { if (n === 0) return 1; return n * factorial(n - 1);}

parentPort?.on('message', (n: number) => { const result = factorial(n); parentPort?.postMessage(result);});

// main.tsimport { Worker } from 'worker_threads';

function runWorker(n: number): Promise<number> { return new Promise((resolve, reject) => { const worker = new Worker('./worker.ts'); worker.postMessage(n); worker.on('message', resolve); worker.on('error', reject); });}

async function main() { const result = await runWorker(20); console.log('20的阶乘:', result);}

main();

每个Worker在自己的线程中运行,拥有自己的事件循环,并且

博客

书籍推荐