Angular里用switchMap取消上一个请求后,为什么偶尔还会收到旧数据?
我在做搜索框的防抖请求,用了switchMap来取消之前的HTTP请求,但有时候输入快一点,还是会收到上一次的响应结果,导致页面显示错乱。这是不是说明switchMap没生效?
我试过加debounceTime(300),也确认了每次输入都会触发新的流,但偶尔旧数据还是冒出来。下面是我的代码:
this.searchInput.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged(),
switchMap(term => this.http.get(<code>/api/search?q=${term}</code>))
).subscribe(results => {
this.results = results;
});
switchMap 确实会取消上一个请求,但问题在于 HTTP 请求可能已经被浏览器缓存了。当你快速输入时,如果新的请求 URL 和之前某个请求的 URL 一样(比如快速输入删除又输入同样的内容),浏览器直接返回缓存的结果,这个速度比取消操作还快。
解决办法很简单,给请求加个时间戳参数强制不走缓存:
还有一种可能是服务端的问题。switchMap 取消的是客户端的等待,但如果请求已经到达服务器并且开始处理,服务端可能还在往外吐数据。这种情况需要在服务端也做一下校验,或者前端加个请求序列号来判断数据是不是最新的。
另外提一句,你代码里那个模板字符串写法好像有点问题,用的是
<code>标签包着的,实际写的时候记得用反引号。可以先试试加时间戳那个方案,大概率能解决。