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 相关文章推荐
angular.bind使用心得
Oct 26 Javascript
如何实现JavaScript动态加载CSS和JS文件
Dec 28 Javascript
详解WordPress开发中get_current_screen()函数的使用
Jan 11 Javascript
jQuery的 $.ajax防止重复提交的两种方法(推荐)
Oct 14 Javascript
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Dec 14 Javascript
微信小程序 限制1M的瘦身技巧与方法详解
Jan 06 Javascript
es6 filter() 数组过滤方法总结
Apr 03 Javascript
小程序实现搜索框功能
Mar 26 Javascript
如何用vue-cli3脚手架搭建一个基于ts的基础脚手架的方法
Dec 12 Javascript
vue.js封装switch开关组件的操作
Oct 26 Javascript
适用于 Vue 的播放器组件Vue-Video-Player操作
Nov 16 Javascript
JS指定音频audio在某个时间点进行播放
Nov 28 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 PDO中文乱码解决办法
2009/07/20 PHP
php下使用curl模拟用户登陆的代码
2010/09/10 PHP
ubutu 16.04环境下,PHP与mysql数据库,网页登录验证实例讲解
2017/07/20 PHP
PHP实现分布式memcache设置web集群session同步的方法
2018/04/10 PHP
PHP+mysql实现的三级联动菜单功能示例
2019/02/15 PHP
PHP配合fiddler抓包抓取微信指数小程序数据的实现方法分析
2020/01/02 PHP
jQuery 注意事项 与原因分析
2009/04/24 Javascript
jQuery之网页换肤实现代码
2011/04/30 Javascript
当jQuery遭遇CoffeeScript的时候 使用分享
2011/09/17 Javascript
这段js代码得节约你多少时间
2011/12/20 Javascript
javascript 判断中文字符长度的函数代码
2012/08/27 Javascript
让AJAX不依赖后端接口实现方案
2012/12/03 Javascript
JQuery处理json与ajax返回JSON实例代码
2014/01/03 Javascript
基于JavaScript代码实现微信扫一扫下载APP
2015/12/30 Javascript
vue下跨域设置的相关介绍
2017/08/26 Javascript
基于node打包可执行文件工具_Pkg使用心得分享
2018/01/24 Javascript
利用js给datalist或select动态添加option选项的方法
2018/01/25 Javascript
Node.JS枚举统计当前文件夹和子目录下所有代码文件行数
2019/08/23 Javascript
用js限制网页只在微信浏览器中打开(或者只能手机端访问)
2020/12/24 Javascript
python利用paramiko连接远程服务器执行命令的方法
2017/10/16 Python
Python paramiko模块的使用示例
2018/04/11 Python
selenium 安装与chromedriver安装的方法步骤
2019/06/12 Python
使用虚拟环境打包python为exe 文件的方法
2019/08/29 Python
python pycharm最新版本激活码(永久有效)附python安装教程
2020/09/18 Python
英国简约舒适女装品牌:Great Plains
2018/07/27 全球购物
Herschel Supply Co.美国:背包、手提袋及配件
2020/11/24 全球购物
程序员经常用到的UNIX命令
2015/04/13 面试题
小学生植树节活动总结
2014/07/04 职场文书
老干部工作先进事迹
2014/08/17 职场文书
家长会欢迎词
2015/01/23 职场文书
员工手册编写范本
2015/05/14 职场文书
2017春节晚会开幕词
2016/03/03 职场文书
详解Mysql 函数调用优化
2021/04/07 MySQL
使用Vue3+Vant组件实现App搜索历史记录功能(示例代码)
2021/06/09 Vue.js
24年收藏2000多部退役军用电台
2022/02/18 无线电
Windows server 2012 配置Telnet以及用法详解
2022/04/28 Servers