Fetch超时设置与终止请求详解


Posted in Javascript onMay 18, 2019

1.基本使用

Fetch 是一个新的端获取资源的接口,用于替换笨重繁琐XMLHttpRequest.它有了Request 和 Response 以及Headers对象的概念,与后端语言请求资源更接近。

一个简单的GET请求

fetch('https://www.baidu.com')
  .then(resp=>resp.text()) // 转换成文本对象
  .then(resp=>console.log(resp)) // 输出请求内容
  .catch(error => console.error(error));

一个简单的POST请求

fetch('https://www.easy-mock.com/mock/5ca59ba44ba86c23d507bd40/example/getUser',{method:"post"})
  .then(resp=>resp.json()) //转换成Json对象
  .then(resp=>console.log(resp)) //输出Json内容
  .catch(error => console.error(error));

更多Fetch相关详细,可查看MDN文档 developer.mozilla.org/en-US/docs/…

2.超时设置

在使用XMLHttpRequest可以设置请求超时时间,可是转用Fetch后,超时时间设置不见了,在网络不可靠的情况下,超时设置往往很有用

ES6以后Promise 出现解决地狱回调等不优雅的代码风格。个人理解这个更像是一个生产者和消费者的关系,查看 Promise文档,有以下两个方法

  1. Promise.race([promise1,promise2]) 传入多个Promise对象,等待最快对象完成
  2. Promise.all([promise1,promise2]) 传入多个Promise 对象,等待所有对象完成

有了以上知识后,结合函数setTimeout就可以实现超时设置

//ahutor:herbert qq:464884492
let timeoutPromise = (timeout) => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve("我是 timeoutPromise,已经完成了");
  }, timeout);
 });
}
let requestPromise = (url) => {
 return fetch(url);
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
 .then(resp => {
  console.log(resp);
 })
 .catch(error => {
  console.log(error);
 });

3.取消请求

将上边的代码拷贝的浏览器控制台并将network设置为Slow3G。运行就会发现,虽然我们在控制台看到了超时信息,但切换到netwok页签中发现请求依然正常进行中,并返回了正确的内容。这并不是我想要的结果,我希望超时时间到了,请求也应该终止。

fetch请求成功后,默认返回一个Response对象,那么我们如何在代码中构造一个这样的对象呢?

timeoutResp=new Response("timeout", { status: 504, statusText: "timeout " })
 successResp=new Response("ok", { status: 200, statusText: "ok " })

AbortController 用于手动终止一个或多个DOM请求,通过该对象的AbortSignal注入的Fetch的请求中。所以需要完美实现timeout功能加上这个就对了

//ahutor:herbert qq:464884492
let controller = new AbortController();
let signal = controller.signal;

let timeoutPromise = (timeout) => {
 return new Promise((resolve, reject) => {
  setTimeout(() => {
   resolve(new Response("timeout", { status: 504, statusText: "timeout " }));
   controller.abort();
  }, timeout);
 });
}
let requestPromise = (url) => {
 return fetch(url, {
  signal: signal
 });
};
Promise.race([timeoutPromise(1000), requestPromise("https://www.baidu.com")])
 .then(resp => {
  console.log(resp);
 })
 .catch(error => {
  console.log(error);
 });

4.总结

第一次在项目中使用fetch,在面向API编程的过程中,发现fetch没有超时的设置。第一时间查看了MDN文档以及向搜索引擎找寻实现功能的灵感(copy+c)。有些朋友在settimeout中通过 reject(new Error('网络超时'))实现。其实这样只是让前端感知当前请求超时了,并没有真正终止本次请求。所以必须借助AbortSignal信号对象。此功能目前还处于试验阶段,使用需谨慎。

demo地址 https://github.com/464884492/blog/blob/master/demo/fetch/fetchdemo.js

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
在textarea中显示html页面的javascript代码
Apr 20 Javascript
javascript innerHTML、outerHTML、innerText、outerText的区别
Nov 24 Javascript
jquery 可拖拽的窗体控件实现代码
Mar 21 Javascript
JavaScript遍历table表格中的某行某列并打印其值
Jul 08 Javascript
JavaScript弹出新窗口后向父窗口输出内容的方法
Apr 06 Javascript
基于BootStarp的Dailog
Apr 28 Javascript
JavaScript动态添加事件之事件委托
Jul 12 Javascript
Vue.js每天必学之Class与样式绑定
Sep 05 Javascript
利用JQuery直接调用asp.net后台的简单方法
Oct 27 Javascript
Node.js中的require.resolve方法使用简介
Apr 23 Javascript
基于vue 实现token验证的实例代码
Dec 14 Javascript
Layui Form 自定义验证的实例代码
Sep 14 Javascript
微信小程序实现搜索历史功能
Mar 26 #Javascript
微信小程序云开发修改云数据库中的数据方法
May 18 #Javascript
小程序云开发教程如何使用云函数实现点赞功能
May 18 #Javascript
微信小程序实现元素渐入渐出动画效果封装方法
May 18 #Javascript
微信小程序收货地址API兼容低版本解决方法
May 18 #Javascript
小程序云开发获取不到数据库记录的解决方法
May 18 #Javascript
小程序云开发之用户注册登录
May 18 #Javascript
You might like
用PHPdig打造属于你自己的Google[图文教程]
2007/02/14 PHP
删除及到期域名的查看(抢域名必备哦)
2008/05/14 PHP
PHP 数据结构 算法 三元组 Triplet
2011/07/02 PHP
修改WordPress中文章编辑器的样式的方法详解
2015/12/15 PHP
yii数据库的查询方法
2015/12/28 PHP
php中static 静态变量和普通变量的区别
2016/12/01 PHP
php + ajax 实现的写入数据库操作简单示例
2020/05/16 PHP
JavaScript 原型学习总结
2010/10/29 Javascript
JS验证控制输入中英文字节长度(input、textarea等)具体实例
2013/06/21 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战一)
2013/08/21 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
JavaScript异步编程Promise模式的6个特性
2014/04/03 Javascript
jQuery解决$符号命名冲突
2016/06/18 Javascript
js内置对象处理_打印学生成绩单的简单实现
2016/09/24 Javascript
jsonp跨域请求实现示例
2017/03/13 Javascript
JS解决position:sticky的兼容性问题的方法
2017/10/17 Javascript
基于Vue的移动端图片裁剪组件功能
2017/11/28 Javascript
Angular4学习教程之DOM属性绑定详解
2018/01/04 Javascript
简化vuex的状态管理方案的方法
2018/06/02 Javascript
JavaScript实现的鼠标跟随特效示例【2则实例】
2018/12/22 Javascript
JavaScript实现连连看连线算法
2019/01/05 Javascript
JS使用Prim算法和Kruskal算法实现最小生成树
2019/01/17 Javascript
vue实现路由不变的情况下,刷新页面操作示例
2020/02/02 Javascript
Vue scoped及deep使用方法解析
2020/08/01 Javascript
[01:38]2018DOTA2亚洲邀请赛主赛事第二日现场采访 神秘商人痛陈生计不易
2018/04/05 DOTA
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
跟老齐学Python之类的细节
2014/10/13 Python
Python面向对象编程中的类和对象学习教程
2015/03/30 Python
Python进程间通信用法实例
2015/06/04 Python
浅谈keras 的抽象后端(from keras import backend as K)
2020/06/16 Python
会计学生自我鉴定
2014/02/06 职场文书
竞聘演讲稿
2014/04/24 职场文书
SpringCloud的JPA连接PostgreSql的教程
2021/06/26 Java/Android
Python实现Excel文件的合并(以新冠疫情数据为例)
2022/03/20 Python
TV动画《神废柴☆偶像》公布先导PV
2022/03/20 日漫
微软Win11 全新照片应用面向 Dev预览版推出 新版本上手体验图集
2022/09/23 数码科技