TypeScript 中的并发与多线程:完整指南

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

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

开始课程

TypeScript中的并发与多线程:从理论到实践



现代Web应用程序需要高性能。TypeScript运行在Node.js之上,提供了强大的工具来同时处理多个任务。本文将探讨TypeScript中并发与多线程的工作原理,并学习如何在实际中应用它们。



并发 vs 并行:关键区别



在深入代码之前,理解并发与并行之间的区别很重要。

  • 并发 — 是程序通过切换任务来处理多个任务的能力。在JavaScript/TypeScript中,这是通过Event Loop和异步操作实现的。
  • 并行 — 是在不同CPU核心上同时执行多个任务。在Node.js中,这是通过Worker Threads实现的。


TypeScript(和JavaScript一样)本质上是单线程的,但通过异步和Worker Threads,我们可以有效地使用这两种方法。



异步:TypeScript中并发的基础



异步编程是迈向并发的第一步。让我们看看主要机制。



Promises 和 async/await



现代TypeScript广泛使用async/await来处理异步操作。这允许编写看起来是同步的,但实际上是并发执行的代码。



// 异步函数示例async function fetchData(url: string): Promise<any> {  const response = await fetch(url);  return response.json();}

// 并发启动多个请求async function fetchAllData(): Promise<void> { const [users, posts, comments] = await Promise.all([ fetchData('/api/users'), fetchData('/api/posts'), fetchData('/api/comments') ]); console.log('所有数据已并发加载');}


Promise.all允许同时启动多个异步操作,与顺序执行相比,这大大加快了执行速度。



异步代码中的错误处理



在并发执行中正确处理错误很重要:



async function safeFetchAll(): Promise<void> {  try {    const results = await Promise.allSettled([      fetchData('/api/users'),      fetchData('/api/invalid'),      fetchData('/api/posts')    ]);        results.forEach((result, index) => {      if (result.status === 'fulfilled') {        console.log(`请求 ${index} 成功:`, result.value);      } else {        console.error(`请求 ${index} 失败:`, result.reason);      }    });  } catch (error) {    console.error('严重错误:', error);  }}


Worker Threads:TypeScript中的真正多线程



对于CPU密集型任务(图像处理、复杂计算),仅靠异步是不够的。这时Worker Threads就派上用场了——它们是真正的执行线程。



创建Worker Thread



让我们看一个在单独线程中计算斐波那契数列的例子:



// 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 runFibonacci(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', (result: number) => { resolve(result); worker.terminate(); }); worker.on('er

博客

书籍推荐