• 仅仅知道如何终止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的基本定义:

    看到这里我们已经知道了答案,但是我们需要再去了解一下上文所说的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的内容。

    我们注意两个地方,一个代表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>
    

    再次运行,我们会得到如下结果:

    从图中我们可以很清楚的看到,请求在2s后被终止,请求状态变为canceled,然后aborted的状态由false转变为true。

    就是这样,我们对fetch也进行的取消操作,还算是豁然开朗吧。嘻嘻。

    兼容性

    虽然AbortController已经诞生很长时间了,但是目前mdn上的定义还是实验性技术,查看mdn我们可以发现,其实主流浏览器大部分都支持了,如果我们开发的平台很新还是可以使用的,相信不远的将来,肯定会大批量使用。前端的道路也会越来越顺畅!

    最后如果这边文章能帮给你带来一点帮助,欢迎关注,点赞,制作不易,与君共勉!

  • 相关阅读:
    [转]The Regular Expression Object Model
    [转]Blue Prism Interview Questions and Answers
    [转]Date and String Function in BluePrism
    [转]Have a query in Blue prism coding stage and collection stage.
    [转]Blue Prism VBO Cheat Sheet
    [转]秒杀系统优化方案之缓存、队列、锁设计思路
    [转]How to: Create a Report Server Database (Reporting Services Configuration)
    [转]Python in Visual Studio Code
    [转]How to Download and Setup Blue Prism
    [转]Blue Prism Architecture
  • 原文地址:https://www.cnblogs.com/xiaoyuxy/p/12346344.html
Copyright © 2020-2023  润新知