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 相关文章推荐
各种效果的jquery ui(接口)介绍
Sep 17 Javascript
javascript检查浏览器是否支持flash的实现代码
Aug 14 Javascript
node.js中的fs.ftruncate方法使用说明
Dec 15 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
Aug 24 Javascript
JavaScript基于原型链的继承
Jun 22 Javascript
关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
Jun 30 Javascript
jQuery bt气泡实现悬停显示及移开隐藏功能的方法
Jul 12 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
Aug 24 Javascript
vue内置组件transition简单原理图文详解(小结)
Jul 12 Javascript
JavaScript中call和apply方法的区别实例分析
Aug 03 Javascript
微信小程序实现图片选择并预览功能
Jul 25 Javascript
在vue中使用image-webpack-loader实例
Nov 12 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&mysql(三)
2006/10/09 PHP
php调用mysql存储过程
2007/02/14 PHP
codeigniter发送邮件并打印调试信息的方法
2015/03/21 PHP
jQuery+Ajax+PHP“喜欢”评级功能实现代码
2015/10/08 PHP
PHP使用PHPexcel导入导出数据的方法
2015/11/14 PHP
php7 安装yar 生成docker镜像
2017/05/09 PHP
laravel实现一个上传图片的接口,并建立软链接,访问图片的方法
2019/10/12 PHP
解密效果
2006/06/23 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
jquery插件tooltipv顶部淡入淡出效果使用示例
2013/12/05 Javascript
JS实现兼容火狐及IE iframe onload属性的遮罩层隐藏及显示效果
2016/08/23 Javascript
jQuery实现点击某个div打开层,点击其他div关闭层实例分析(阻止冒泡)
2016/11/18 Javascript
jquery实现自定义图片裁剪功能【推荐】
2017/03/08 Javascript
layer 刷新某个页面的实现方法
2019/09/05 Javascript
[03:08]TI9战队档案 - Vici Gaming
2019/08/20 DOTA
Python实现合并字典的方法
2015/07/07 Python
Python中的getopt函数使用详解
2015/07/28 Python
详解Python的Flask框架中生成SECRET_KEY密钥的方法
2016/06/07 Python
python发送邮件实例分享
2017/07/28 Python
python爬虫之urllib3的使用示例
2018/07/09 Python
Django实战之用户认证(初始配置)
2018/07/16 Python
Python函数基础实例详解【函数嵌套,命名空间,函数对象,闭包函数等】
2019/03/30 Python
Python提取转移文件夹内所有.jpg文件并查看每一帧的方法
2019/06/27 Python
python实现动态数组的示例代码
2019/07/15 Python
python读取raw binary图片并提取统计信息的实例
2020/01/09 Python
Python如何使用OS模块调用cmd
2020/02/27 Python
班组长安全生产职责
2013/12/16 职场文书
给民警的表扬信
2014/01/08 职场文书
青蓝工程实施方案
2014/03/27 职场文书
大学活动总结格式
2014/04/29 职场文书
班级文化建设标语
2014/06/23 职场文书
乡镇干部党的群众路线教育实践活动个人对照检查材料
2014/09/24 职场文书
大学生联谊活动策划书(光棍节)
2014/10/10 职场文书
工作违纪的检讨书范文
2019/07/09 职场文书
Python访问Redis的详细操作
2021/06/26 Python
详解OpenCV获取高动态范围(HDR)成像
2022/04/29 Python