我想使用 HTTP 拦截器,以便每个 HTTP 请求与下一个请求之间有 500 毫秒的延迟。我目前正在从在 app.module 上注册并注入(inject)到我的组件中的可注入(inject)服务发出这些请求。在同一个模块中,我注册了我的拦截器。
//delay-interceptor.ts
@Injectable()
export class DelayInterceptor implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return timer(500).pipe(
delay(500),
switchMap(() => next.handle(request))
)
}
}
//app.module.ts
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: DelayInterceptor,
multi: true
},
ManageHousesService
]
//manage-houses.component.ts
createHouses() {
this.houses.foreach((house: House) => {
this.createHousesService.createHouse(house.name).subscribe(createdHouse => {
house.rooms.foreach((room: Room) => {
this.createHousesService.createRoom(house.id, room.name).subscribe();
});
});
});
}
//manage-houses.service.ts
createHouse(houseName: string): Observable<House> {
return this.httpClient.post(`${this.apiUrl}/houses`, { houseName: houseName });
}
createRoom(houseId: string, roomName: string): Observable<Room> {
return this.httpClient.post(`${this.apiUrl}/houses/${houseId}/rooms`, { roomName: roomName });
}
在我的组件中,我必须以嵌套方式发出请求。我有一个房屋列表,我想为每个房屋创建一个房间列表。因此,对于每个房屋,我都会发出 POST 请求,并在订阅时使用新创建的房屋的 ID 来创建房间。对于每个房间,我都会发出包含房间信息和房屋 ID 的 POST 请求。现在这就是问题出现的地方。在每个房屋请求之间,延迟有效,但在房屋的所有房间之间则不然,我不明白为什么会发生这种情况。
我想这可能与在每个 foreach 中调用相同的方法有关,这可能会重用相同的可观察值或类似的东西,因此不会触发 HTTP 拦截器,但我不确定。在拦截器上,我尝试同时使用计时器和延迟方法,但两种方法都得到了相同的结果。
最佳答案
你认为每个请求最多需要 500 毫秒? 可能需要更长的时间
您是否尝试过使用async/await
?
你可以使用await
来处理这个异步代码,而且最好避免在异步代码中使用forEach
,因为forEach
不是一个 promise 感知,这就是它的设计方式
所以最好使用普通的 for 循环
或 ES6 for of 循环
我们还需要像现在一样使用async/await
来摆脱订阅和取消订阅,我们需要处理promises
而不是observables
为此,RxJS
提供了 toPromise()
运算符,它将 Observable
转换为 promise
,以便您可以使用 promises
而不是 Observables
来使用 HttpClient
方法
toPromise()
返回一个 Promise
,它由该 Observable
发出的第一个值解析(它内部调用 subscribe
为您并用 Promise
对象包装它)。
然后您可以将 createHouses
函数更新为类似的内容
async createHouses() {
for (const house of this.houses) {
// wait for the house to be added to db
await this.createHousesService.createHouse(house.name).toPromise();
// then loop over the rooms
for (const room of house.rooms) {
// wait for the room to be added to the db
await this.createHousesService.createRoom(house.id, room.name).toPromise()
}
}
}
希望它能满足您的需要
关于javascript - Angular HTTP 请求延迟拦截器未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61036431/