angular - 一系列 HTTP 请求没有按顺序出现。然后可能会在最后一个请求上显示旧请求
问题描述
我使用 Angular 8 创建了我的 Web 应用程序的界面。问题是当我发送多个请求时,它们没有按顺序到达。这会引起很多问题。例如,当用户快速浏览页面时,有时会显示错误的页面。
- 使用 RxJS 的最佳解决方案是什么?
- 我可以对我的所有请求使用拦截器吗?
这是一个使用 HttpClient 检索项目的示例片段:
listOptions = {
start: 0,
length: 10
};
private fillCards() {
this.companyService.getList(this.listOptions).subscribe(res => {
if (res.code === 1) {
this.list = res.data; // This list is displayed in the view
}
});
}
public pageChange() {
// Set list parameters
this.listOptions.start = (this.page - 1) * this.pageSize;
this.listOptions.length = this.pageSize;
// Reload the cards
this.fillCards();
}
公司服务中的列表功能:
constructor(private http: HttpClient, private appSettings: AppSettings) {}
getList(options = new ApiListOptions()) {
return this.http.post<ApiResponse<CompanyGet[]>>(
this.appSettings.ApiRoot + 'company/list',
options
);
}
解决方案
如果我正确理解您的问题,每次用户导航到下一页时,您都会向后端发出请求以加载该页面。如果他们多次点击下一页按钮,这将导致多个请求被并行触发,最后一个返回“wins”,即显示那些结果。
有很多方法可以解决这个问题。一 - 您可以禁用 UI 中的导航按钮,直到最新请求完成。这样,用户将不得不等到能够再次导航。
同样在 UI 中,您可以为用户提供跳转到特定结果页面的可能性,这样他们就不必点击 5 次即可到达第 5 页。
另一种方法不是在单击时立即触发 http 请求,而是等待一段时间,以查看用户是否仍然单击按钮以到达更远的页面。您将使用debounceTime
延迟 http 请求。
有关如何实现此目的,请参见以下示例:https ://angular-s3qpgc.stackblitz.io
您的组件将维护一个“点击队列”,并将任何按钮点击放入其中:
clickQueue = new Subject();
pageNumber = 0;
getDataAsync(): void {
this.clickQueue.next(this.number++);
}
您将使用 订阅此队列debounceTime(500)
,以便您仅在用户停止点击 500 毫秒后才采取行动。switchMap
运营商确保,如果用户在发送请求后再次开始点击,挂起的 http 调用将被取消(并且其结果被丢弃)
ngOnInit() {
this.clickQueue.pipe(
debounceTime(500),
switchMap(num => this.callService(num))
).subscribe(result => {
console.log(result);
});
}
在我的示例中,该callService
函数模拟 http 调用,该调用将在 500-1000 毫秒之间的随机时间后返回。
callService(number) {
return new Observable(subscriber => {
setTimeout(() => {
subscriber.next(number);
subscriber.complete();
}, 500 + Math.random() * 500);
});
}
在示例中,您可以看到当您单击“立即获取数据”按钮时会发生什么——这就是您当前的情况。与使用 debounceTime 和 switchMap 的“获取数据异步”相反,这将导致预期的行为。
最后一点:正如其他人所说,每次调用subscribe()
Observable 时,都必须unsubscribe
稍后再调用,否则会在应用程序中造成内存泄漏和奇怪的错误。这是另一个主题,您可以查看例如这篇文章:https ://blog.angularindepth.com/the-best-way-to-unsubscribe-rxjs-observable-in-the-angular-applications-d8f9aa42f6a0
推荐阅读
- security - Laravel (API) 护照令牌安全
- c++ - c++程序如何在调试时读取VSCode中的用户输入
- docker - GitLab CI docker 构建失败
- html - 在 Github Pages 我的网站不显示照片
- excel - 将空白单元格返回为空白而不是 0 的索引公式
- string - 我如何在 unity2d 中消除这个讨厌的错误?
- java - 如何在自定义 JComponent 中正确实现 MouseInputListener
- jenkins - groovy.lang.MissingPropertyException:没有这样的属性:类的道具:groovy.lang.Binding
- concurrency - 无法识别死锁
- python - 如何将数据帧从长转换为宽,索引中的值按年份分组?