背景
搜索框功能修改,由之前通过防抖在规定时间内输入只触发最后一次输入搜索结果,更改为边输入边搜索边展示结果。这样可能就会出现接口返回结果比较慢或者是多次请求中有的接口返回结果比最后一次返回结果要慢,导致最终结果不是最新结果,这就需要我们再请求过程中去终止上一次请求。
终止上一次请求的方法,不同的请求有不同的方法,因为项目问题,我这里使用的是Promise.race()实现的。
Promise.race()(粗略说下是干什么的,详细了解请百度~)
将多个Promise实例包装成一个新的Promise实例。
多个Promise实例中有任意一个解决或拒绝,返回的就是该Promise实例的解决或拒绝。
通过Promise.race()实现
this.cancel = () => {};
function fetchResult() { // input输入事件
this.cancel(); // 高频率输入时取消上一个请求
const abortRequest = new Promise(resolve => this.cancel = resolve);
Promise.race([abortRequest, 请求接口的Promise对象)]).then(ret => {
// 判断请求结果 如果是因为高频取消上一个请求的话this.cancel()并没有传值
if (ret) {
// 请求结果
}
});
}
扩展下~
终止上一次其他请求的方法
- xhr:xhr.abort()
- axios:axios.CancelToken
- fetch:AbortController
使用方法(简单粗略版)
xhr
const xhr = new XMLHttpRequest();
const method = 'GET';
const url = 'https://xxx';
xhr.open(method, url, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {}
}
xhr.send();
// 想要去终止请求时直接调用 xhr.abort() 即可。
axios
let self = this; // 可能会存在this指向问题
axios.get(url, {
cancelToken: new axios.CancelToken(function executor(c) {
self.source = c;
})
}).then(ret => {
});
// 想要去终止请求时直接调用this.source() 即可。
fetch
const controller = new AbortController();
const signal = controller.signal;
fetch(url, {signal}).then((ret) => {
});
// 想要去终止请求时直接调用controller.abort() 即可。
参考
ES6 入门教程: Promise对象
高频率请求时如何模拟取消上一个Fetch请求
仅仅知道如何终止XHR请求,或许对你来说是不够的!