TypeScript 异步编程入门
现代 Web 开发离不开异步编程。无论是 API 请求、文件系统操作还是定时器——所有这些操作都需要非阻塞代码执行。TypeScript 作为 JavaScript 的超集,为处理异步操作提供了强大的工具,同时增加了严格的类型检查和更好的代码可读性。
在本指南中,我们将详细讲解 TypeScript 中异步编程的所有方面:从基础的 Promise 到使用 async/await 的高级模式以及并行任务执行。
1. TypeScript 中的 Promise 基础
什么是 Promise?
Promise(承诺)是一个表示异步操作结果的对象。它可以处于以下三种状态之一:
- Pending(待定)——初始状态,操作尚未完成。
- Fulfilled(已完成)——操作成功完成。
- Rejected(已拒绝)——操作以错误结束。
创建带类型注解的 Promise
TypeScript 允许严格地为 Promise 的返回值指定类型。来看一个例子:
// 返回 Promise 并指定数据类型的函数function fetchUserData(userId: number): Promise<User> { return new Promise<User>((resolve, reject) => { setTimeout(() => { const user: User = { id: userId, name: '伊万·伊万诺夫', email: 'ivan@example.com' }; if (userId > 0) { resolve(user); } else { reject(new Error('无效的用户 ID')); } }, 1000); });}
// 用于数据类型的接口interface User { id: number; name: string; email: string;}
// 使用 PromisefetchUserData(1) .then((user: User) => { console.log(`用户: ${user.name}`); }) .catch((error: Error) => { console.error(`错误: ${error.message}`); });Promise 链式调用
可以将 Promise 串联起来,以顺序执行异步操作:
function getUserPosts(userId: number): Promise<string[]> { return new Promise((resolve) => { setTimeout(() => resolve(['帖子 1', '帖子 2', '帖子 3']), 500); });}
function getPostComments(postTitle: string): Promise<string[]> { return new Promise((resolve) => { setTimeout(() => resolve(['评论 1', '评论 2']), 300); });}
// Promise 链式调用fetchUserData(1) .then((user) => { console.log(`找到用户: ${user.name}`); return getUserPosts(user.id); }) .then((posts) => { console.log(`找到帖子数: ${posts.length}`); return getPostComments(posts[0]); }) .then((comments) => { console.log(`第一篇帖子的评论数: ${comments.length}`); }) .catch((error) => { console.error('发生错误:', error); });2. Async/Await——现代方法
async/await 语法
关键字 async 和 await 使异步代码看起来像同步代码,从而显著提高了可读性。标记为 async 的函数总是返回一个 Promise。
// 带返回值类型注解的异步函数async function loadUserProfile(userId: number): Promise<UserProfile> { try { const user = await fetchUserData(userId); const posts = await getUserPosts(userId); return { user, posts, lastLogin: new Date()```