type
status
date
slug
summary
tags
category
icon
password
如何取消 HTTP 请求?是在面试过程中经常遇到的一个问题,并且在日常开发中也会遇到,比如不使用防抖的情况下如何取消请求,再比如一个请求等待时间过长,用户不想等了,可以取消这个请求。
最近在使用 Angular 的过程中,用到了 switchMap 操作符,发现每次发送新的请求时,上一个请求都会被自动取消掉,为了探究原理,就有了本文章。
我们知道,浏览器能发送请求,靠两个重要的 API,一个是比较老旧的 XHR,另一个比较新的 Fetch。所以本文会分别介绍使用 XHR 和 Fetch 如何取消请求,并且会分析一下 Angular 内置的 http 模块是怎样取消请求的。
XHR 取消请求
为了测试,首先创建一个
index.html 文件,内容如下,并且我们会使用 http://httpbin.org/ 提供的开放 API 来发送和取消请求。XHR 使用实例的
abort() 方法来取消请求。先点击
Begin,并且在 3 秒内点击 Abort,效果如下:
可以看到,在点击 Abort 的时候,当前的 HTTP 请求的 Status 会变成 canceled 的状态。
Fetch 取消请求
Fetch 使用
AbortController 来取消请求。同样先点击
Begin,并且在 3 秒内点击 Abort,效果如下:
可以看到,当点击
Abort 之后会调用 controller 实例的 Abort 方法,并且在 singal 上订阅的 abort event 也会被执行。与 XHR 不同的是,控制台会多打印一条 Error 信息。Angular 中的 http 模块取消请求
了解了 XHR 和 Fetch 取消请求的方式之后,我们来看一下 Angular 中是使用的哪种方式。
首先在 sandbox 上创建一个 Angular 项目,地址:演示代码
通过多次点击按钮可以发现,每次点击都会先取消上一个请求,并且发送新的请求。那么 Angular 和 RxJS 内部是怎么实现的呢?
带着这个问题,我们首先来看 switchMap 的代码:switchMap
其中有这么几行是我们关心的:
我们知道 switchMap 操作符的行为是每次上游产生数据的时候都会去调用函数参数 project,只要有新的内部 Observable 产生,就会立刻退订之前的内部 Observable 对象,所以 Angular 中取消 http 请求的代码应该是该请求内部 Observable 的返回值,比如对应到演示代码中就是
this.http.get(url)方法内部 Observable 的返回值。接下来我们去查看 Angular http 模块的
get 方法,地址:client.ts通过查看代码,可以发现
get 方法会调用一个名为 handle 的函数,这个函数返回了一个 Observable,而这个 Observable 的返回值也是一个函数,代码如下:通过
abort 和变量命名也能猜出来,Angular 中内置的 http 模块是使用的 XHR 来发送请求,更详细的过程可以阅读 Angular http 模块的源码。- Author:大胖猫
- URL:http://preview.tangly1024.com/article/how-to-cancel-http-request
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!









