关于前端取消请求,大多数文章都是new AbortController() 然后将signal放到请求中,然后执行abort取消,这种文章怎么好意思拿出来啊,mmmmini版的官方文档罢了。
首先要明确我们想要的效果是什么,可以对比一下toast.showloading(),当我们发起一个请求打开loading时,什么时候关闭是由我们随时随地决定的。随时就不解释了,随地就是我在组件中打开了loading,我可以其他任何组件中关闭这个loading。
话不多说,看我操作
首先封装一个全局公共类
export default class CancelManager {cancelMapstatic instanceconstructor() {this.cancelMap = new Map()this.cancelKey = []}static getInstance() {if (!CancelManager.instance) {CancelManager.instance = new CancelManager()}return CancelManager.instance}has(key) {return this.cancelMap.has(key)}hasCancel(key) {return this.cancelKey.includes(key)}getSignal(key) {if (!key) {console.log('getSignal的key不能为空')return}const controller = new AbortController()const { signal } = controllerthis.cancelMap.set(key, controller)return signal}cancel(key) {const task = this.cancelMap.get(key)if (!task) {console.log(key + '控制器不存在')return}task.abort()this.delete(key)this.cancelKey.push(key)console.log(key, '请求已取消,cancelKey=>>', this.cancelKey)}cancelAll() {this.cancelMap.forEach((task) => {task.abort()})this.cancelKey = []this.cancelMap.clear()}delCancelKey(key) {this.cancelKey = this.cancelKey.filter((v) => v !== key)}delete(key) {this.cancelMap.delete(key)}clear() {this.cancelMap.clear()}
}
使用
//这里的id也可是是这个函数,因为里面是用的Map存储,保证唯一性即可,以及方便在其他地方能拿到这个idconst controller = CancelManager.getInstance()//单例模式随处get都行const signal = controller.getSignal(id)//此处只需将signal传给axios等请求库就行了const res = await getData(params, { signal })
取消
const controller = CancelManager.getInstance()controller.cancel(id)