首页 前端知识 优雅的终止Fecth和异步任务

优雅的终止Fecth和异步任务

2024-06-07 12:06:18 前端知识 前端哥 64 423 我要收藏

优雅的终止Fecth和异步任务

自从有了Promise,我们编写异步任务就变的很简单的。避免了层层嵌套的回调函数。自身提供的统一接口更方便的管理、控制一步任务。

当然,Promise也有自己的不足、比如无法取消。

因此、有了AbortController。目前官方只有Fetch Api实现了该机制;其实我们自己可以通过该对象(AbortController)实现优雅的取消异步任务

AbortController

[MDN]AbortController接口表示一个控制器对象,允许你根据需要中止一个或多个 Web请求

如何创建一个AbortController对象

 let controller = new AbortController();

上文创建的AbortController对象,提供一个属性(signal)和一个方法(abort)来控制异步任务

  • signal属性,用于设置事件的监听器

  • abort方法,用于取消任务,当执行abort()方法时,

    • controller.signal 会触发abort事件
    • controller.signal.aborted 的值为true
使用方法
 var controller=new AbortController();//新建一个controller对象
 ​
 controller.signal.addEventListener('abort',console.log); //监听controller.signal的abort事件
 ​
 controller.abort(); //取消
 ​
 console.log(controller.signal.aborted) //输出signal.aborted属性,由于执行了abort方法,这里变成了true

输出:

  1. Event {isTrusted: true, type: ‘abort’, target: AbortSignal, currentTarget: AbortSignal, eventPhase: 2, …}
  2. true

注意:

注意:

  • abort() 被调用时,fetch() promise 拒绝一个名为 AbortErrorDOMException

与Fetch一起使用

fetch,执行一个web请求

fetch返回的是一个promise,promise的缺点是无法取消的,所以我们借助AbortController对象来取消,

查看fetch文档、我们发现option配置有个signal配置,这个就是fecth官方对于AbortController的支持,直接使用就行

伪代码:
 var url="...";
 var controller=new AbortController();
 fetch(url,{
     signal:controller.signal
 })
 //fetch 内部会对signal进行监听,如果遇到abort事件,fetch将终止请求
封装一个完整实例
 //定义一个Http类,封装fetch操作
 class Http{
     constructor(){
         this.ctrl=new AbortController();
     }
     query(url,options){
         var controller=this.ctrl;
         return fetch(url,Object.assign({ signal: controller.signal},options||{}))
         
     }
     abort(){
          this.ctrl.abort();
     }
 }//实例化Http对象
 var http=new Http();//调用方法
 http.query('https://www.baidu.com').then(res=>{
     console.log("success")
 }).catch(err=>console.log);setTimeout(function(){
     //终止请求
     http.abort();
 },10)//output:
 //DOMException: The user aborted a request.

注意:

  • AbortController是可以取消多个fetch任务的,也就是多个fetch任务都使用了同一个AbortController对象的signal属性

取消自定义异步任务

前面说到AbortController也可取消其他的异步任务,现在我们来看看吧,

其实就是利用AbortController对象的singal属性的abort事件来取消自定义异步任务

class AsyncTask{
     constructor(){
         this.ctrl=new AbortController();
         this.time=3000
     }
     run(){
         return new Promise((resolve,reject)=>{
             //这里使用setTimeout来模拟异步任务
             const timer=setTimeout(function(){
                 console.log('success')
                 resolve()
             },this.time)
             this.ctrl.signal.addEventListener('abort', error=>{
                 clearTimeout(timer)
                 reject(error)
             });
         })
         
     }
     abort(){
          this.ctrl.abort();
     }
 }
 ​
 ​
 var at=new AsyncTask();
 at.run().catch(err=>{
     console.log(err)
 })
 //异步任务在2s后取消
 setTimeout(function(){
     at.abort()
 },2000)

总结

  • AbortController利用singal属性,abort方法就可以终止异步任务
  • AbortController对象执行abort方法时、触发signal属性abort事件,signal.aborted属性变成true
  • fetch接口内部已经实现AbortController机制,通过signal属性配置
  • AbortController对象可以用于取消自定义异步任务
转载请注明出处或者链接地址:https://www.qianduange.cn//article/11230.html
标签
评论
发布的文章

1.10 Unity中的数据存储 JSON

2024-06-13 21:06:30

JSON 数据格式化方法

2024-06-13 21:06:26

大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!