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操作JSON要领详细总结
Aug 25 Javascript
探讨JavaScript中的Rest参数和参数默认值
Jul 29 Javascript
使用jQuery操作HTML的table表格的实例解析
Mar 13 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 Javascript
Vue.js每天必学之计算属性computed与$watch
Sep 05 Javascript
老生常谈JQuery data方法的使用
Sep 09 Javascript
React Router基础使用
Jan 17 Javascript
jquery实现一个全局计时器(商城可用)
Jun 30 jQuery
vue项目如何刷新当前页面的方法
May 18 Javascript
关于微信小程序获取小程序码并接受buffer流保存为图片的方法
Jun 07 Javascript
vue使用codemirror的两种用法
Aug 27 Javascript
javascript实现评分功能
Jun 24 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
动态网站web开发 PHP、ASP还是ASP.NET
2006/10/09 PHP
PHP 获取远程网页内容的代码(fopen,curl已测)
2011/06/06 PHP
php数组一对一替换实现代码
2012/08/31 PHP
php实现QQ小程序发送模板消息功能
2019/09/18 PHP
锋利的jQuery 第三章章节总结的例子
2010/03/23 Javascript
JavaScript利用构造函数和原型的方式模拟C#类的功能
2014/03/06 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
2015/06/12 Javascript
详解JavaScript基于面向对象之继承
2015/12/13 Javascript
JavaScript jquery及AJAX小结
2016/01/24 Javascript
基于js中的原型、继承的一些想法
2016/08/10 Javascript
JS中页面与页面之间超链接跳转中文乱码问题的解决办法
2016/12/15 Javascript
整理关于Bootstrap过渡动画的慕课笔记
2017/03/29 Javascript
Vue2.x中的父子组件相互通信的实现方法
2017/05/02 Javascript
nodejs+mongodb+vue前后台配置ueditor的示例代码
2018/01/02 NodeJs
js装饰设计模式学习心得
2018/02/17 Javascript
python随机生成指定长度密码的方法
2015/04/04 Python
Python的Tornado框架实现图片上传及图片大小修改功能
2016/06/30 Python
matplotlib绘制动画代码示例
2018/01/02 Python
VSCode下配置python调试运行环境的方法
2018/04/06 Python
python 实现在Excel末尾增加新行
2018/05/02 Python
python 读取Linux服务器上的文件方法
2018/12/27 Python
python opencv minAreaRect 生成最小外接矩形的方法
2019/07/01 Python
pandas 层次化索引的实现方法
2019/07/06 Python
python树的同构学习笔记
2019/09/14 Python
基于FME使用Python过程图解
2020/05/13 Python
python 数据库查询返回list或tuple实例
2020/05/15 Python
详解pandas获取Dataframe元素值的几种方法
2020/06/14 Python
python的launcher用法知识点总结
2020/08/07 Python
Linux不知道文件后缀名怎么判断文件类型
2012/04/26 面试题
光电信息专业应届生求职信
2013/10/07 职场文书
安全生产投入制度
2014/01/29 职场文书
现场活动策划方案
2014/08/22 职场文书
2014年人事科工作总结
2014/11/19 职场文书
2015年城市管理工作总结
2015/05/23 职场文书
Nginx进程调度问题详解
2021/09/25 Servers
如何使用SQL Server语句创建表
2022/04/12 SQL Server