一.场景
- 有这么一个场景,有一个搜索框,每当你输入内容改变的时候,就会去调用一个接口,返回当前输入内容的关联字,但是吧第二次响应的速度可能会比第一次快,页面的内容先变成第二次的内容,再变成第一次的内容,这就造成了一个关联字不对的问题,如图。
有两种解决这个问题的方案:
- 第一种是去进行防抖(多次调用只执行最后一次),节流(一段时间去执行一次)。
- 第二种控制ajax的传输,在第后面的请求发送前取消掉前面的。
- 介于文章的标题所以这里仅对第二种进行介绍。
二. XMLHttpRequest的取消请求
XMLHttpRequest的取消很简单,只需要在创建XMLHttpRequests的变量上面,调用abort方法。
let xhr = new XMLHttpRequest()
xhr.open('请求方法','请求地址')
xhr.send()
xhr.abort()
三.AbortController Api(mdn网址)
使用方法很简单,这是一个构造函数,可以把这个构造函数视为一个观察者。哪个请求在请求的时候携带上了这个观察者AbortController.signal属性,观察者就可以去观察到它,这个属性返回的是一个AbortSignal对象。
mdn官方定义:
AbortSignal
接口表示一个信号对象(signal object),它允许你通过 AbortController 对象与 DOM 请求(如 Fetch)进行通信并在需要时将其中止。
对象上面的aborted属性表示请求的状态是终止还是未终止。reason属性表示一旦信号被中止的原因。
let btn = document.querySelector('button')
let Controller;
btn.onclick = function(){
Controller&& Controller.abort()
Controller = new AbortController()
let signal = Controller.signal
fetch('地址',{
signal
})
}
获取按钮并给它绑定事件,每次点击校验Controller 是否有观察的请求有则取消掉前面观察的请求,每次都创建一个新的观察者,观察后面的请求,后面的请求携带观察者的signal属性。
调用观察者的abort属性会去报一个错误,the user aborted a request(这个用户取消掉了这个请求)
可以用try catch去捕获这个错误,弹出一个消息提示用户:"你输入的太快了,上一次的请求我给你取消掉了",当然更多的时候是不提升用户。