优雅的终止Fecth和异步任务

优雅的终止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对象可以用于取消自定义异步任务
### Git Fetch Git Pull 的区别及用法 #### 定义与功能 Git fetch 命令用于将远程主机的最新内容拉取到本地,但不会自动合并这些更改至当前分支。这意味着用户可以先查看新引入的内容再决定如何处理它们[^2]。 相比之下,`git pull` 不仅会从指定的远程仓库获取最新的代码提交信息,还会尝试立即将其与本地的工作副本中的相应分支进行自动化合操作。这一过程相当于连续执行了 `git fetch` 加上 `git merge` 两个动作[^1]。 ```bash # 使用 git fetch 获取更新而不立即应用 $ git fetch origin # 查看已获取的新改动(可选) $ git log HEAD..origin/main # 手动合并来自远端的变化 $ git merge origin/main ``` 对于希望更谨慎地管理项目变更的人来说,采用上述方式通过单独调用 `fetch` `merge` 可以提供更大的灵活性以及更好的控制力;而对于那些追求效率并愿意承担可能遇到冲突的风险,则可以直接使用 `pull` 来简化流程[^4]。 #### 合并与冲突处理 当运行 `git pull` 并发生冲突时,开发者必须暂停手头的任务去解决这些问题才能继续前进。而利用 `git fetch` ,则允许开发人员事先评估是否有任何潜在的问题存在,并计划好应对策略后再采取行动[^3]。 #### 安全性考量 因为 `git fetch` 不会引起现有文件结构上的即时变动,所以通常被认为是一种更为保守的选择,适合于想要保持工作环境稳定性的场景下使用。另一方面,尽管 `git pull` 提供了一种便捷的方法来同步修改,但由于它涉及到了直接的操作,所以在某些情况下可能会带来意想不到的结果,特别是在面对复杂的历史记录或是多线程协作环境中尤为如此。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端3K小哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值