在现代前端应用中,组合多个API请求并处理其结果是一种常见的需求。使用TypeScript可以帮助我们在处理异步操作时保持类型安全。下面是一个示例,展示了如何使用async/await
和Promise
从多个API获取数据,并优雅地处理潜在错误和类型定义。
文末有我帮助400多位同学成功领取到前端offer的面试综合题哦,包含了工程化,场景题,八股文,简历模板,等等
定义API接口类型
首先,定义我们将要请求的API的响应数据类型。这有助于TypeScript进行静态类型检查,确保我们在处理数据时不会出现类型错误。
// apiTypes.ts
export interface User {
id: number;
name: string;
}
export interface Post {
id: number;
title: string;
authorId: number;
}
export interface UserProfile {
user: User;
posts: Post[];
}
实现数据获取服务
接着,我们创建一个服务函数,该函数会异步地从两个API(一个获取用户信息,另一个获取该用户的所有帖子)获取数据,并将结果合并。
// dataService.ts
import fetch from 'cross-fetch'; // 或使用其他fetch库
import { User, Post, UserProfile } from './apiTypes';
// 异步函数获取用户信息
async function fetchUser(userId: number): Promise<User> {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`Failed to fetch user with id ${userId}`);
}
return response.json() as Promise<User>;
}
// 异步函数获取用户的帖子列表
async function fetchPostsByUser(userId: number): Promise<Post[]> {
const response = await fetch(`https://api.example.com/posts?authorId=${userId}`);
if (!response.ok) {
throw new Error(`Failed to fetch posts for user with id ${userId}`);
}
return response.json() as Promise<Post[]>;
}
// 主函数,组合上述两个API调用
export async function fetchUserProfile(userId: number): Promise<UserProfile> {
try {
const [user, posts] = await Promise.all([
fetchUser(userId),
fetchPostsByUser(userId),
]);
return { user, posts };
} catch (error) {
// 根据需要处理错误,例如记录日志或抛出自定义错误
console.error('Error fetching user profile:', error);
throw error; // 重新抛出,以便调用者也可以处理错误
}
}
使用服务并处理结果
最后,在你的应用中调用fetchUserProfile
函数,并处理可能抛出的错误。
// 在某个组件或服务中使用
import { fetchUserProfile } from './dataService';
async function loadUserProfile(userId: number) {
try {
const userProfile: UserProfile = await fetchUserProfile(userId);
console.log('User Profile:', userProfile);
// 在这里处理或展示数据
} catch (error) {
console.error('Failed to load user profile:', error);
// 可以在此处提供用户友好的错误提示
}
}
// 调用函数
loadUserProfile(1);
小结
- 类型定义:明确地定义API响应的数据类型,有助于保持代码的清晰和健壮。
- 错误处理:使用try-catch块处理
fetchUserProfile
中的异常,确保了错误的统一处理,同时也允许调用者进一步处理错误。 - async/await与Promise.all:结合使用
async/await
和Promise.all
来并发请求多个API,提高了代码的可读性和效率。 - 重新抛出错误:在
catch
块中重新抛出错误,使得错误可以被更高层的错误处理逻辑捕获,增加了灵活性。