基于 fetch 的请求封装
原生 fetch 请求失败后(如无网络)状态会变成 reject 走 .catch 。绝大多数情况下业务场景只需要给个 toast 等简单处理。每个请求都 .catch 会显得格外繁琐,并且如果不 .catch, .then 里面的后续处理不会触发,可能会导致逻辑中断。
基于上述情况,可以封装公共请求方法处理异常情况,返回固定格式 { code, data, massage }, 只需在 .then 里面获取数据并处理。
目标
- 保留 fetch 语法不变
- 返回 promise,且状态一定变成 resolve,返回固定数据格式 { code, data, message }
- 给 url 动态添加域名
- 默认失败弹出 toast,且提供开关
- 默认请求中 loading,且提供开关
实现
实现如下
/**
* 返回 Promise({ code, data, message});
*/
import { message } from 'antd';
import { dispatch } from '../index';
import { startLoading, endLoading } from '../store/globalSlice';
// 在 config/env.js 中设置
export const origin = process.env.ORIGIN;
interface MyInit extends RequestInit {
noToastError?: boolean; // 默认false
noLoading?: boolean; // 默认false
}
// 请求返回统一格式
export class Response {
code: number;
data: any;
message: string | null;
constructor(code: number, data: any, message: string | null) {
this.code = code;
this.data = data;
this.message = message;
}
}
export default (input: RequestInfo, myInit?: MyInit) => {
const init: MyInit = myInit || {};
// url 动态添加 origin
if (typeof input === 'string') {
if (!/https?:\/\//.test(input)) {
input = origin + input;
}
}
// 开始 loading
if (!init?.noLoading) {
dispatch(startLoading());
}
// 请求
return fetch(input, {
headers: {
'Content-Type': 'application/json',
},
...init,
})
.then((resp) => {
// code 不为 2xx
if (!/^2\d{2}$/.test(String(resp.status))) {
return new Response(resp.status, null, null);
}
return resp
.json()
.then((json) => {
// toast错误信息
if (json.code !== 0) {
message.error(json.message);
}
// 退出登陆
if (json.code === 20001) {
// logout();
// window.location.pathname = '/login';
}
// 请求成功的数据
return json;
})
.catch((err) => {
// 不是 json 格式
return new Response(999998, null, 'data is not json.');
});
})
.catch((err) => {
// 请求发送失败
message.error('您的网络可能不通,请确认后重试');
return new Response(999999, null, err);
})
.finally(() => {
// 结束 loading
if (!init?.noLoading) {
dispatch(endLoading());
}
});
};
目前只完成了对 json 数据的处理。
其中 loading 部分用了 redux 和 @reduxjs/toolkit,用一个变量记录当前请求个数,控制实际 loading 开始和结束,实现如下:
let count = 0;
export const startLoading = () => (dispatch: any) => {
if (count === 0) {
dispatch(setLoding(true));
}
count++;
};
export const endLoading = () => (dispatch: any) => {
count--;
if (count === 0) {
dispatch(setLoding(false));
}
};
使用
import myfetch from './myfetch.ts';
myfetch('/xxx/xxx')
.then(res => console.log(res))
myfetch('https://www.xxx.com/xxx/xxx')
.then(res => console.log(res))
myfetch('/xxx/xxx', {
methods: 'POST',
body: JSON.stringify({}),
})
.then(res => console.log(res))
myfetch('/xxx/xxx', {
methods: 'POST',
body: JSON.stringify({}),
noToastError: true,
noLoading: true,
})
.then(res => console.log(res))
基于 fetch 的请求封装的更多相关文章
- 简单的基于Vue-axios请求封装
具体实现思路=>封装之前需要用npm安装并引入axios,使用一个单独的js模块作为接口请输出对象,然后export dafult 这个对象. 1.首先我们需要在Vue实例的原型prototyp ...
- React Native 网络请求封装:使用Promise封装fetch请求
最近公司使用React作为前端框架,使用了异步请求访问,这里做下总结: React Native中虽然也内置了XMLHttpRequest 网络请求API(也就是俗称的ajax),但XMLHttpRe ...
- react-native fetch 请求封装
1.fetch 函数封装 fetch.js /** * 请求头 * @type {{Accept: string, Content-Type: string}} */ const header = { ...
- uniapp 基于 flyio 的 http 请求封装
之前写请求都是用别人封装好的,直接 import request 完事,自己第一次写还是一头雾水,学习了一波搞清楚了些,可以写简单的封装了. 首先要搞清楚为什么封装请求,同其他的封装一样,我们把不同请 ...
- 基于小程序请求接口 wx.request 封装的类 axios 请求
基于小程序请求接口 wx.request 封装的类 axios 请求 Introduction wx.request 的配置.axios 的调用方式 源码戳我 feature 支持 wx.reques ...
- WebApi系列~基于单请求封装多请求的设计
回到目录 怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能 ...
- iOS开发之网络请求(基于AFNetworking的再封装)
最近一直很忙也没有什么时间写博客了.放假了休息一下,就写一篇博客来总结一下最近做项目中出现过的问题吧!!! 首先,在项目中我的起到了什么作用,无非就是把美工(UI设计师)给我们的图显示出来,然后再和服 ...
- webapi基于单请求封装多请求的设计【转】
怎么说,单请求封装多请求,这句话确实有点绕了,但还是要看清楚,想明白这到底是怎么一回事,单请求即一次请求(get,post,put,delete),封闭多请求,即在客户端发送的一个请求中可能包含多个子 ...
- fetch 如何请求数据
fetch 如何请求数据 在 传统Ajax 时代,进行 API 等网络请求都是通过XMLHttpRequest或者封装后的框架进行网络请求,然而配置和调用方式非常混乱,对于刚入门的新手并不友好 二 与 ...
随机推荐
- Java实现 蓝桥杯 图书排列(全排列)
标题:图书排列 将编号为1~10的10本书排放在书架上,要求编号相邻的书不能放在相邻的位置. 请计算一共有多少种不同的排列方案. 注意,需要提交的是一个整数,不要填写任何多余的内容. 9 9 10 9 ...
- java算法集训代码填空题练习1
1 报数游戏 有n个孩子站成一圈,从第一个孩子开始顺时针方向报数,报到3的人出列,下一个人继续从1报数,直到最后剩下一个孩子为止.问剩下第几个孩子.下面的程序以10个孩子为例,模拟了这个过程,请完善之 ...
- Java实现第八届蓝桥杯杨辉三角
杨辉三角 杨辉三角也叫帕斯卡三角,在很多数量关系中可以看到,十分重要. 第0行: 1 第1行: 1 1 第2行: 1 2 1 第3行: 1 3 3 1 第4行: 1 4 6 4 1 - 两边的元素都是 ...
- Linux 服务管理-服务分类
Linux中的服务根据安装方法的不同可以分为RPM包默认安装的服务和源码包安装的服务,而RPM包安装的服务又依据启动和自启动的不同分为独立服务和基于xinetd服务. 查看已经安装的服务 查看所有RP ...
- 你都这么拼了,面试官TM怎么还是无动于衷?
前言 面试,对于每个人而然并不陌生,可以说是必须经历的一个过程了,小到一场考试,大到企业面试,甚至大型选秀...... 有时自己明明很努力了,但偏偏会在面试环节出了插曲,比如,紧张就是最容易出现的了. ...
- layui导出表格的两种方法
一.不熟悉layui小白使用方法 1.引入如下js文件: 2.编写如下函数: 3.表格ID要与函数取值保持一致即可,再就是自定义一个按钮触发事件 二.引入插件使用方法 1.layui官网下载插件包: ...
- 数列计算I(整理四舍五入)
问题 C: 数列计算I(点击) 时间限制: 1 Sec 内存限制: 128 MB ...
- Dorado开发——树形下拉框
最近在学习Dorado开发的过程中,遇到了一个问题,Dorado的树形下拉框选择:Dorado默认情况下父节点和子节点都是可选的,而我要实现的是父节点不可选. 解决办法:在下拉框中,判断父子节点,点击 ...
- 匿名实现类&匿名对象
学习过程中经常搞不清匿名类&匿名对象怎么用,今天就把常用的方式总结一遍. 1.创建了非匿名实现类的非匿名对象 //定义USB接口 interface USB{ void inputInofo( ...
- Excel经典教程之一
照片名称:未命名 照片名称:自动筛选 照片名称:在Excel中字符替换 照片名称:在Excel中直接编辑“宏” 照片名称:在Excel中为导入外部数据 照片名称:在Excel中行列快速转换 照片名称: ...