仅仅知道如何终止XHR请求,或者许对你来说是不够的!
TLDR:
当我们需要的时候,我们可以通过AbortController接口来终止一个或者者多个请求。
前言
到目前为止,我们有两个常用的基本的手段去发送请求进而局部刷新页面内容,其一是XMR(XMLHttpRequest),其二是fetch,我们一个个说
XHR
对于XHR,我们或者许已经很熟习了,当我们想要发送一个请求的时候,我们可以这样做:
const xhr = new XMLHttpRequest();const method = 'GET';const url = 'https://xxx';xhr.open(method, url, true);xhr.onreadystatechange = () => { if (xhr.readyState === 4) { // do something }}xhr.send();
当我们因为某种起因(比方重复请求)想要终止它的时候,我们只要要调用abort就可。
xhr.abort();
很方便也很简洁,但是对于fetch呢?
fetch
首先我们看下fetch的基本定义:
接受一个必需的参数和一个可选的参数
- 定义要获取的资源,地址或者者Request对象
- 可选的配置对象,比方请求方式、body、credentials等等,其中我们需要知道的是
signal
,他的定义如下:
一个AbortSignal对象实例,允许你通过AbortController与fetch请求通信或者者终止fetch
返回值是一个promise
看到这里我们已经知道了答案,但是我们需要再去理解一下上文所说的AbortController
.
AbortController
最初es6引入fetch的时候,其实就是没有abort这样的功能,不过广大程序朋友们还会希望能有这个灵活的api,所以在2015年就有人提了这个issue,再次之后大家尝试了注入promise式的取消或者者是其余hack等等,经过这份折腾最终我们迎来了AbortController和AbortSignal。
AbortController目前很简单,有一个制度的属性AbortController.signal
和一个用来中断请求的.abort()
光说也没啥意思,咱看代码说话:
// 启动一个node服务,其中包括一个api和一个html页面const Koa = require('koa');const fs = require('fs');const app = new Koa();const sleep = () => { return new Promise(res => { setTimeout(function() { res(); }, 3000); });};app.use(async ctx => { if (ctx.request.url === '/api') { await sleep(); ctx.body = 'Hello World'; } else { ctx.status = 200; ctx.respond = false; fs.createReadStream('./test.html').pipe(ctx.res); }});app.listen(3000);
下面是test.html的内容
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <script> fetch('/api') .then((res) => { console.log(res, '请求成功'); }); </script></body></html>
启动服务后,我们看下network的内容。
image
我们注意两个地方,一个代表fetch请求,一个代表请求的延时时间,也就是我们定义的三秒
取消fetch
这时候我们想中断,即可以这样做:
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title></head><body> <script> // 添加了如下几行 const controller = new AbortController(); const signal = controller.signal; console.log(signal, 'signal的初始状态'); signal.addEventListener('abort', function (e) { console.log(signal, 'signal的中断状态'); }); setTimeout(function() { controller.abort(); }, 2000); // 添加部分结束 fetch('/api', {signal}) .then((res) => { console.log(res, '请求成功'); }); </script></body></html>
再次运行,我们会得到如下结果:
imageimage
从图中我们可以很清楚的看到,请求在2s后被终止,请求状态变为canceled,而后aborted的状态由false转变为true。
就是这样,我们对fetch也进行的取消操作,还算是豁然开朗吧。嘻嘻。
兼容性
尽管AbortController已经诞生很长时间了,但是目前mdn上的定义还是试验性技术
,查看mdn我们可以发现,其实主流浏览器大部分都支持了,假如我们开发的平台很新还是可以使用的,相信不远的将来,一定会大批量使用。前台的道路也会越来越顺畅!
image
最后假如这边文章能帮给你带来一点帮助,欢迎关注,点赞,制作不易,与君共勉!
image
1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是摆设,本站源码仅提供给会员学习使用!
7. 如遇到加密压缩包,请使用360解压,如遇到无法解压的请联系管理员
开心源码网 » 仅仅知道如何终止XHR请求,或者许对你来说是不够的!