面试题答案
一键面试实现方案描述
- 使用
concatMap
操作符:concatMap
操作符会按照顺序处理 Observable 发出的值,并将每个值映射为一个新的 Observable,只有当前面的 Observable 完成时,才会处理下一个。这确保了请求按顺序执行。 - 错误处理:使用
catchError
操作符来捕获每个请求过程中可能出现的错误,在捕获到错误后,可以选择合适的处理方式,比如返回一个默认值或者重新抛出错误。
完整代码示例
假设我们有一个服务类 UserService
来处理这些请求:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { catchError, concatMap, map, Observable, of } from 'rxjs';
interface User {
id: number;
name: string;
// 假设权限字段
permissionField: string;
}
interface Permission {
// 权限相关的字段
accessLevel: string;
}
interface DataList {
data: string[];
}
@Injectable({
providedIn: 'root'
})
export class UserService {
constructor(private http: HttpClient) {}
getUserInfo(): Observable<User> {
return this.http.get<User>('/api/user-info');
}
getPermissions(user: User): Observable<Permission> {
return this.http.get<Permission>(`/api/permissions/${user.permissionField}`);
}
getAccessibleData(permission: Permission): Observable<DataList> {
return this.http.get<DataList>('/api/accessible-data', {
params: { accessLevel: permission.accessLevel }
});
}
getAllData(): Observable<DataList> {
return this.getUserInfo()
.pipe(
concatMap((user) => this.getPermissions(user).pipe(
catchError((error) => {
console.error('权限请求错误', error);
// 这里可以返回一个默认的权限对象
return of({ accessLevel: 'default' });
})
)),
concatMap((permission) => this.getAccessibleData(permission).pipe(
catchError((error) => {
console.error('数据列表请求错误', error);
// 这里可以返回一个默认的数据列表
return of({ data: [] });
})
))
);
}
}
在组件中使用这个服务:
import { Component } from '@angular/core';
import { UserService } from './user.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
dataList: string[] = [];
constructor(private userService: UserService) {
this.userService.getAllData().subscribe((data) => {
this.dataList = data.data;
});
}
}
解释
UserService
类:包含三个方法分别对应三个异步请求。getAllData
方法使用concatMap
操作符将三个请求按顺序连接起来,并使用catchError
处理每个请求可能出现的错误。- 组件
AppComponent
:注入UserService
并调用getAllData
方法,订阅结果并更新组件中的数据。