javascript - Angular HTTP 请求延迟拦截器未按预期工作

标签 javascript angular http rxjs delay

我想使用 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/

相关文章:

javascript - 模态关闭按钮

javascript - 如何为我的网站创建需要用户身份验证的书签

javascript - Angular 2动态组件点击事件

java - 在 DNS 重定向错误的情况下,发送的正确 HTTP 响应是什么?

Angular 10 : Code doesn't wait for subscribe to finish

javascript - node.js 会取代 tomcat 吗?

javascript - 订购 key :value pairs of objects

angular - 检查 Angular 2+ 中使用的 api 凭据的最佳实践

javascript - 如何访问使用 <ng-content> 投影的任意 Angular 子组件中的方法?

rest - 如何设计一个查询,从中检索要以 RESTful 方式应用过滤器的资源的最后数据?