-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch()
方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。
fetch(String url, [, Object options]).then(function(response) { ... }).catch(err => {})
目前,浏览器端原生获取数据,发请求的主要是 XMLHttpRequest
和 fetch
,XMLHttpRequest
作为元老级的存在, fetch
是在 ES6 中推出的更现代的 API。XMLHttpRequest
本身是支持请求中断的 abort
, 而 fetch
不支持 abort
,不过目前可以通过 AbortController
实现。
fetch
设计之初是不支持中断的,开发者 2015 年在 GitHub 上提的 issue ,目前解决方案还在讨论阶段,其中就包括 cancelable-promises 及其他 hack 方法。const c = new FetchController fetch(url, {controller: c}) c.abort() // 或 fetch(url, {controller: c => c.abort()})
但是,现在有了通用的 AbortController
和 AbortSignal
API,这些 API 是由 DOM 标准规范 提供的,而不是由语言本身提供的。
什么是 AbortController?
AbortController
接口代表一个控制器对象,允许在需要时中止一个或多个 DOM 请求。
使用 AbortController.AbortController()
构造函数创建一个新的 AbortController
对象。 使用 AbortSignal
对象完成与DOM请求的通信。
// 构造一个新的 AbortController 对象实例
AbortController.AbortController() // 目前大部分浏览器不支持此方法构造
const controller = new AbortController()
// 返回一个AbortSignal对象实例,它可以用来 with/abort 一个DOM请求
AbortController.signal
// 中止一个尚未完成的DOM请求, 能够中止fetch 请求,任何响应Body的消费者和流
AbortController.abort()
以下是 AbortController
的基本用法
// 创建 AbortController 的实例
const controller = new AbortController()
const signal = controller.signal
// 监听 abort 事件,在 controller.abort() 执行后执行回调打印
signal.addEventListener('abort', () => {
console.log(signal.aborted) // true
})
// 触发中断
controller.abort()
浏览器支持情况
查询支持情况 AbortController,整体支持性不是特别好, 可以使用 abort-controller/polyfil,abort-controller控件。
使用 AbortController 中断 fetch 请求
fetch
接受 AbortSignal
作为第二个参数的一部分。
const controller = new AbortController()
const signal = controller.signal
fetch('http://jd.com', { signal })
.then(r => r.json())
.then(response => console.log(response))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Fetch was aborted')
} else {
console.log('Error', err)
}
})
// 在 2s 后中断请求,将触发 'AbortError'
setTimeout(() => controller.abort(), 2000)
触发 controller.abort()
会中断 fetch
的 request 和 response。AbortController
不仅适用于 fetch
,可以适用到中止任意异步事件。
思考
客户端中断请求反馈失败提示,但服务端会出现真实处理,状态变成成功了,导致客户端刷新页面状态变更了,那这种不一致一般使用优化策略 幂等机制。