前言
项目中遇到一个问题,在连续发送同一个请求时,如果第二次请求比第一次请求快,那么实际显示的是第二次请求的数据,这就会造成数据和我选择的内容不一致的问题。解决的方案:在后续发送请求时,判断之前的请求是否完成(同一个接口),如果未完成则立即取消,然后在发送新的请求。而前端常用的发送请求的方式无非是两种,一种是利用ajax封装请求的Axios,一种是利用H5新特性的Fetch进行请求,接下来我们针对这两种请求简述一下如何中断请求。
如何中断请求
Axios
想要中断Axios请求,就需要清楚Axios的底层调用的是什么。Axios基于ajax进行封装,底层调用的是
XMLHttpRequest
。中断Axios如果该请求已被发出,
XMLHttpRequest.abort()
方法将终止该请求,当一个请求被终止,它的readyState
将被置为XMLHttpRequest.UNSENT(0)
,并且请求的status
置为0。Axios内置
CancelToken
类,并且new时可以传入回调函数,回调函数接受一个参数cancel函数,CancelToken会把取消回调注入给参数callback,外部使用cancelCallback接收。
CancelToken构造函数生成
cancel
函数
async request() { try { if (typeof this.cancelCallback === 'function') { this.cancelCallback('请求中断') this.cancelCallback = null } const ret = await axios.get({ data: {}, cancelToken: new axios.CancelToken(callback => this.cancelCallback = callback) }) } catch (error) { console.log(error) } }
CancelToken.source()生成取消令牌
token
let cancelTokenSource = null; async request() { if (cancelTokenSource) { cancelTokenSource.cancel('请求中断') cancelTokenSource = null } const cancelToken = axios.CancelToken cancelTokenSource = cancelToken.source() try { const ret = await axios.get({ cancelToken: cancelTokenSource.token, data: {} }) } catch (error) { console.log(error) } }
Fetch
Fetch是H5新添加的功能,在低版本是不支持的,比如: ie。为了中断Fetch请求跟随出现了
AbortController
一个控制器对象,允许你根据需要中止一个或者多个web请求。
AbortController
通过在请求中传入信号源
,然后在需要中断请求的时候通过abort
方法进行中断请求。
AbortController
类生成会返回abort
中断请求的方法和signal
中断请求匹配的信号源。
// 1. 创建 abortController 对象 const abortControllerObj = new AbortController() // 2. 创建信号源 const signal = abortControllerObj.signal // 3. 使用 const request = async () => { try { const ret = await fetch('/api/task/list', { signal }) return ret } catch (error) { console.log(error) } } // 4. 中断 abortControllerObj.abort()
结语
中断请求在开发需求的难免会碰到,如果在前期封装公司级请求中加入中断请求的功能也是进行了功能优化。大家可以学习一下,从而完善自己的请求封装函数。最后如果文章对你有用,请帮忙点赞,关注+评论。🙏🙏🙏