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调试工具 Javascript Debug Toolkit 2.0.0版本发布
Dec 02 Javascript
javascript globalStorage类代码
Jun 04 Javascript
Js如何判断客户端是PC还是手持设备简单分析
Nov 22 Javascript
js查看一个函数的执行时间实例代码
Sep 12 Javascript
学习JavaScript设计模式之责任链模式
Jan 18 Javascript
基于javascript实现全国省市二级联动下拉选择菜单
Jan 28 Javascript
JavaScript实现解析INI文件内容的方法
Nov 17 Javascript
深入学习Bootstrap表单
Dec 13 Javascript
JavaScript获取ul中li个数的方法
Feb 13 Javascript
Node.js 异步异常的处理与domain模块解析
May 10 Javascript
微信小程序自定义tab实现多层tab嵌套功能
Jun 15 Javascript
封装微信小程序http拦截器过程解析
Aug 13 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 开发的 8 个技巧
2007/01/02 PHP
Zend Framework动作助手Url用法详解
2016/03/05 PHP
PHP如何使用Memcached
2016/04/05 PHP
Yii框架实现邮箱激活的方法【数字签名】
2016/10/18 PHP
ThinkPHP5.0框架使用build 自动生成模块操作示例
2019/04/11 PHP
Bootstrap入门书籍之(一)排版
2016/02/17 Javascript
jQuery窗口拖动功能的实现代码
2017/02/04 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
2017/03/09 Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
2017/05/05 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
JavaScript复制内容到剪贴板的两种常用方法
2018/02/27 Javascript
详解从买域名到使用pm2部署node.js项目全过程
2018/03/07 Javascript
详解vue2.0+axios+mock+axios-mock+adapter实现登陆
2018/07/19 Javascript
Vue 实现拖动滑块验证功能(只有css+js没有后台验证步骤)
2018/08/24 Javascript
vue1.0和vue2.0的watch监听事件写法详解
2018/09/11 Javascript
后台使用freeMarker和前端使用vue的方法及遇到的问题
2019/06/13 Javascript
《javascript设计模式》学习笔记四:Javascript面向对象程序设计链式调用实例分析
2020/04/07 Javascript
详解JavaScript作用域、作用域链和闭包的用法
2020/09/03 Javascript
Python3基础之list列表实例解析
2014/08/13 Python
使用grappelli为django admin后台添加模板
2014/11/18 Python
使用C语言扩展Python程序的简单入门指引
2015/04/14 Python
python 剪切移动文件的实现代码
2018/08/02 Python
3个用于数据科学的顶级Python库
2018/09/29 Python
linux 下python多线程递归复制文件夹及文件夹中的文件
2020/01/02 Python
selenium+python配置chrome浏览器的选项的实现
2020/03/18 Python
Pytho爬虫中Requests设置请求头Headers的方法
2020/09/22 Python
matplotlib设置颜色、标记、线条,让你的图像更加丰富(推荐)
2020/09/25 Python
HTML5响应式(自适应)网页设计的实现
2017/11/17 HTML / CSS
解释一下ArrayList Vector和LinkedList的实现和区别
2013/04/26 面试题
在C#中如何实现多态
2014/07/02 面试题
办理居住证介绍信
2014/01/15 职场文书
《奇妙的国际互联网》 教学反思
2014/02/25 职场文书
单位个人查摆问题及整改措施
2014/10/28 职场文书
新生开学寄语大全
2015/05/28 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
执行力心得体会范文
2016/01/11 职场文书