前言
俺是梅十三,一只躺平的猫,觉得有意思就分享点东西
promise
这玩意的基本用法大家都知道,我就不再赘述,他有一个特点,一旦初始化,就不能中止。
不过,他有个状态叫pennding
,意思就是你不返回resolve
也不返回reject
,他就会一直这么挂着不走下去,等你把他要的给了,他才愿意往下走,你要说这有啥用?我们看个例子
代码很简单,点击开始按钮啥也不干5秒后显示接受,如果中间你点了一下中止按钮,那就显示躺平,在到5s之前,在你中止他之前,他就一直是pennding
,他的resolve状态由自己内部控制,而他的reject状态被我们拿了出来由我们控制,这样就很简单的实现了一个promise的中止效果。
上面代码块的codeSendBox,觉得有意思想运行看看的,可以点进去
AbortController
有人可能奇怪既然可以自己实现外部控制promise
的状态,为什么还需要专门的api呢,再用这个AbortController
不是多此一举么?
答案是当然不是,我们都知道现在主流的网络请求是axios
和fetch
,一个是基于xhr
封装的,用的xhr
的api实现中止请求功能,一个是浏览器原生支持的,但是没有原生的中止请求api,fetch
就是用abortController
实现的中止请求功能。这就直接证明了这个api的价值。但是在介绍AbortController
之前我们先回顾一下上面的例子,中止promise
其实是有一点响应式的感觉,promise
会立即响应状态的变更,但我们改变状态的方法不是响应式的,而是一个取巧的方法,把reject
函数返回给了一个中间变量,并且把这个中间变量存储在专用的容器里,然后我们再通过这个容器去执行中间变量对应的reject
,reject
的内容由外部决定,这其实很不合理,因为具体reject
什么不应该是外部要关注的,这会让这个promise
变得难以理解,且维护也更加苦难,毕竟还有一个容器要一起维护。
而AbortController
则解决了我们上述的问题,它改变状态的方法也是响应式的,我们不需要劫持reject
或者resolve
,也不需要容器。
现在我们来介绍一下这个api,这个东西是一个控制器对象,但我觉得这么说不形象,说它是一套遥控炸弹设备比较形象,一套两件,一件炸弹,一件遥控器,
const controllerSuit = new AbortController(); // 实例化遥控炸弹套件
const signal = controllerSuit.signal // 拿出炸弹
const controller = controllerSuit.abort // 拿出遥控器
我们可以看到,就两个属性,非常简单,接下来看一下使用的实例
下面代码块的codeSendBox,觉得有意思想运行看看的,可以点进去
这是模拟了一个fetch
请求中止的实现,也就是用abortController
实现的中止promise
,总体思路也很简单,专门封一个受控promise
里面塞上炸弹signal
,然后和请求的request
一起塞到race
里,你要是想终止了,就按一下桶里的遥控器,然后挂在signal
上的事件立马就会执行,炸弹爆炸,请求中止。
你可能会好奇了,这个signal
炸弹为什么可以注册事件在上面?因为这东西它继承了EventTarget
,是一个dom
接口,可以接受事件,创建侦听器,这也是他为什么可以响应式的执行,炸弹么,不响应那就是残次品了
我们可以看到这个signal
是麻雀虽小,但五脏俱全,你按下遥控器,它内部的aborted
就会变为true
,然后就会执行你绑定的事件,是不是很好理解,哈哈。
结语
第一次发文章,工作时间也不长,肯定有很多写的不好的地方,希望大家多多批判,不要留情。