仅仅知道如何终止XHR请求,或者许对你来说是不够的!

作者 : 开心源码 本文共2420个字,预计阅读时间需要7分钟 发布时间: 2022-05-13 共120人阅读

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的基本定义:

  • 接受一个必需的参数和一个可选的参数

    1. 定义要获取的资源,地址或者者Request对象
    2. 可选的配置对象,比方请求方式、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请求,或者许对你来说是不够的!

发表回复