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入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
Jquery 动态循环输出表格具体方法
Nov 23 Javascript
JavaScript实现的内存数据库LokiJS介绍和入门实例
Nov 17 Javascript
js模拟淘宝网的多级选择菜单实现方法
Aug 18 Javascript
图解Sublime Text3使用技巧
Dec 21 Javascript
解决给dom元素绑定click等事件无效问题的方法
Feb 17 Javascript
基于jQuery和CSS3实现APPLE TV海报视差效果
Jun 16 jQuery
webpack+vue中使用别名路径引用静态图片地址
Nov 20 Javascript
ES6之模版字符串的具体使用
May 17 Javascript
jQuery实现table表格信息的展开和缩小功能示例
Jul 21 jQuery
使用vue-cli4.0快速搭建一个项目的方法步骤
Dec 04 Javascript
JavaScript对象原型链原理解析
Jan 22 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
建立动态的WML站点(二)
2006/10/09 PHP
asp和php下textarea提交大量数据发生丢失的解决方法
2008/01/20 PHP
php is_file()和is_dir()用于遍历目录时用法注意事项
2010/03/02 PHP
linux下删除7天前日志的代码(php+shell)
2011/01/02 PHP
php 字符串中的\n换行符无效、不能换行的解决方法
2014/04/02 PHP
php使用parse_url和parse_str解析URL
2015/02/22 PHP
比较完整的微信开发php代码
2016/08/02 PHP
PHP中单例模式与工厂模式详解
2017/02/17 PHP
浅谈PHP中new self()和new static()的区别
2017/08/11 PHP
PHP运用foreach神奇的转换数组(实例讲解)
2018/02/01 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
jquery 插件 人性化的消息显示
2008/01/21 Javascript
jquery+php随机生成红包金额数量代码分享
2015/08/27 Javascript
基于jquery编写分页插件
2016/03/07 Javascript
从零学习node.js之详解异步控制工具async(八)
2017/02/27 Javascript
Angular5升级RxJS到5.5.3报错:EmptyError: no elements in sequence的解决方法
2018/04/09 Javascript
基于angular6.0实现的一个组件懒加载功能示例
2018/04/12 Javascript
微信小程序实现留言板功能
2018/11/02 Javascript
Vue中用props给data赋初始值遇到的问题解决
2018/11/27 Javascript
JavaScript基础之this和箭头函数详析
2019/09/05 Javascript
Vue自定义组件的四种方式示例详解
2020/02/28 Javascript
Vue插槽_特殊特性slot,slot-scope与指令v-slot说明
2020/09/04 Javascript
[44:41]Fnatic vs Liquid 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
按日期打印Python的Tornado框架中的日志的方法
2015/05/02 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
python 读取Linux服务器上的文件方法
2018/12/27 Python
python-Web-flask-视图内容和模板知识点西宁街
2019/08/23 Python
HTML5中原生的右键菜单创建方法
2016/06/28 HTML / CSS
美国网上眼镜商城:Zenni Optical
2016/11/20 全球购物
2014年民主评议党员工作总结
2014/12/02 职场文书
长城导游词
2015/01/30 职场文书
2015年测量员工作总结
2015/05/23 职场文书
承诺书的内容有哪些,怎么写?
2019/06/21 职场文书
python文本处理的方案(结巴分词并去除符号)
2021/05/26 Python
pycharm代码删除恢复的方法
2021/06/26 Python
Html5同时支持多端sdk的小技巧
2021/11/17 HTML / CSS