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 相关文章推荐
JS 去除Array中的null值示例代码
Nov 20 Javascript
js charAt的使用示例
Feb 18 Javascript
AngularJS入门教程(零):引导程序
Dec 06 Javascript
javascript针对cookie的基本操作实例详解
Nov 30 Javascript
JavaScript 链式结构序列化详解
Sep 30 Javascript
jQuery图片切换动画特效
Nov 02 Javascript
JavaScript提高加载和执行效率的方法
Feb 03 Javascript
VueJs监听window.resize方法示例
Jan 17 Javascript
爬虫利器Puppeteer实战
Jan 09 Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
利用Webpack实现小程序多项目管理的方法
Feb 25 Javascript
JS 5种遍历对象的方式
Jun 16 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
php与XML、XSLT、Mysql的结合运用实现代码
2009/11/19 PHP
php基于Snoopy解析网页html的方法
2015/07/09 PHP
php使用Jpgraph创建折线图效果示例
2017/02/15 PHP
php实现将数据做成json的格式给前端使用
2018/08/21 PHP
Thinkphp 框架基础之入口文件功能、定义与用法分析
2020/04/27 PHP
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
30个最佳jQuery Lightbox效果插件分享
2011/04/11 Javascript
关于jQuery中的each方法(jQuery到底干了什么)
2014/03/05 Javascript
js动态切换图片的方法
2015/01/20 Javascript
直接拿来用的页面跳转进度条JS实现
2016/01/06 Javascript
JS中对Cookie的操作详解
2016/08/05 Javascript
用原生js统计文本行数的简单示例
2016/08/19 Javascript
H5移动端图片压缩上传开发流程
2016/11/09 Javascript
Node.js之网络通讯模块实现浅析
2017/04/01 Javascript
JavaScript之filter_动力节点Java学院整理
2017/06/28 Javascript
JavaScript代码实现txt文件的上传预览功能
2018/03/27 Javascript
解决vue自定义全局消息框组件问题
2019/11/22 Javascript
微信小程序图片右边加两行文字的代码
2020/04/23 Javascript
解决vue项目,npm run build后,报路径错的问题
2020/08/13 Javascript
[27:39]Ti4 循环赛第二日 LGD vs Fnatic
2014/07/11 DOTA
教你安装python Django(图文)
2013/11/04 Python
python3操作mysql数据库的方法
2017/06/23 Python
Python matplotlib画图实例之绘制拥有彩条的图表
2017/12/28 Python
Python实现的视频播放器功能完整示例
2018/02/01 Python
使用 Python ssh 远程登陆服务器的最佳方案
2020/03/06 Python
手工制作的意大利礼服鞋:Ace Marks
2018/12/15 全球购物
瑞典多品牌连锁店:Johnells
2021/01/13 全球购物
装潢设计专业推荐信模板
2013/11/26 职场文书
公益广告宣传方案
2014/02/28 职场文书
大学社团活动总结
2014/04/26 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
《失物招领》教学反思
2016/02/20 职场文书
MySQL kill不掉线程的原因
2021/05/07 MySQL
详解Vue的列表渲染
2021/11/20 Vue.js
HTML+JS实现在线朗读器
2022/02/15 Javascript