sketion-http
v0.1.33
Published
skeleton-option-http
Downloads
4
Readme
// 这是0.1.0之后的文档介绍,旧的文档在这里
更新日志 0.0.3 --> 0.1.1
- 移除了
SketionConfig
类型中的showLoading
,showWarn
,showError
,closeLoading
,'requestIsSuccess'方法 - 移除了
SketionRequestOptions
类型中的showLoading
,loadingText
,showError
,showWarn
,silent
属性 createSketion
新增afterRequest
,beforeRequest
,getDataFromCache
关于新增的createSketion
的三个方法的说明。(Q为SketionRequestOptions的子类型,R为自定义请求结果类型)
| 名称 | 说明 | 类型 | 必填 |
| ---------------- | ---------------- | --------------------------------------------- | ---- |
| beforeRequest | 请求发起之前调用 | (request?: Q) => void | y |
| afterRequest | 请求发起之后调用 | (response: R, request?: Q) => R | Promise | y |
| getDataFromCache | 获取缓存 | (request?: Q) => R | n |
升级指南
建议原 showLoading
的逻辑移至 beforeRequest
中,
原showWarn
,showError
,showWarn
,closeLoading
的逻辑移至afterRequest
中
介绍
sketion-http: 意为skeleton-option-http
sketion-http
主要功能就是将一次请求的流程与结果标准化
请求流程为 sketion-http
规定,请求结果则在使用时由用户定义
sketion-http
规定的请求流程大致为
请求发起 -> 加载状态
-> 请求完成,加载结束
-> 请求成功
或 请求失败,展示接口报错信息
sketion-http
不依赖任何请求库,只要求在发送请求时返回一个promise
类型的对象,所以可以配合axios
、fetch
、ajax
甚至小程序使用
使用
推荐使用 typescript
- 准备工作
在使用之前,你需要创建自己的 'Request
' 对象,举例来说
axios
发送请求时接收的是AxiosRequestConfig
对象,要求你传入url
,method
,data
等属性
因此,你可以创建一个名为MyRequest
的类型,继承AxiosRequestConfig
,这样MyRequest
对象也能拥有url
等属性了。
使用createSketion
创建一个SketionHttp<Q,R>
对象,SketionHttp
支持泛型,并有两个泛型参数,
参数Q
传入的'Request
'对象,规定请求对象的类型,参数R
是传出的'Response
'对象,规定请求结束在业务代码中拿到的结果类型。
sketion-http
规定,类型Q
必须继承SketionRequestOptions
类型。
因此,MyRequest
还要继承SketionRequestOptions
interface MyRequest extends SketionRequestOptions,AxiosRequestConfig{
// 可以添加自己另需的属性
extraStr?:string;
loadingText?: string;
showLoading?: boolean;
}
或者
type MyRequest = SketionRequestOptions&AxiosRequestConfig&{
// 可以添加自己另需的属性
extraStr?:string;
}
MyRequest
继承AxiosRequestConfig
是因为要调用axios
来发送请求,
继承SketionRequestOptions
是因为要根据其属性判断时候需要展示加载状态或提示错误
创建MyResponse
则没有这么多限制,只需要根据接口返回的数据来就行
{
"data": [
{
"id": 1,
"name": "小明",
"time": "15:36",
"status": 1
},
],
"code": 0,
"msg": "成功"
}
这是一段普通由接口的json
数据,它包含了data
、code
、msg
三个字段
所以创建的MyResponse
对象也包含这三个字段,_originalData_
用于保存原始信息
interface StandardResponse<T=any>{
code:number;
msg: string;
data: T;
_originalData_: any;
}
class MyResponse<T = any> implements StandardResponse<T> {
public code: number
public msg: string
public data: T
public _originalData_: any;
constructor(res:StandardResponse) {
this.code = res.code
this.msg = res.msg
this.data = res.data
this._originalData_ = res._originalData_
}
// 添加判断请求是否成功的快捷方法
public get success() {
return this.code === 0
}
}
调用sketion-http
发送请求的方法最终会返回一个泛型为MyResponse
的Promise
对象,使用then
方法
即可接收到MyResponse
对象
- 创建
sketion
实例(配合axios
)
// 创建一个`axios`对象,用户发送网络请求
const myAxios = axios.create({
baseURL: baseUrl,
timeout: 10000,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: [
function (data) {
// 'Content-Type': 'application/x-www-form-urlencoded' 需要配合 `qs.stringify` 来转换数据
return qs.stringify(data)
}
],
timeoutErrorMessage:'请求超时(10s),请检查网络或联系管理员',
})
// 使用`createSketion` 创建一个`sketion`对象
const sketionUtil = createSketion<MyRequest,MyResponse>({
getDataFromCache: (request) => {
console.log("getDataFromCache", request);
// 这里可以根据url和参数来定位缓存数据
// 示例中为了方便,固定返回一个成功值
return new MyResponse(0, "登陆成功拉", {}, {});
},
beforeRequest: (request) => {
if (request && request.showLoading)
Toast.loading({
message: request?.loadingText || "加载中...",
forbidClick: true,
duration: 0,
});
},
afterRequest: (response, request) => {
console.log("--afterRequest--", response);
if (request && request.toastToken) {
request?.toastToken.close();
Toast.clear();
} else {
Toast.clear();
}
Toast.clear();
if (!response.success) {
Notify({ type: "warning", message: response.msg });
}
return response;
},
sendRequest(request) {
return myAxios(request as MyRequest);
},
parseRes(res: any) {
const axiosRes = res as AxiosResponse;
if (axiosRes.status === 200) {
if (axiosRes.data) {
return Promise.resolve(
new MyResponse(
axiosRes.data.code,
axiosRes.data.msg,
axiosRes.data.data,
axiosRes
)
);
} else {
return new MyResponse(500, "res.data is null", null, axiosRes);
}
} else {
return new MyResponse(res.status, res.statusText, null, axiosRes);
}
},
parseError(error: Error) {
return new MyResponse(500, error.message, null, error);
},
})
- 使用
const login = (params: TypeParams) => {
return sketionUtil.sendRequest({
url: '/api/login',
method: 'POST',
data: params,
loadingText: '登录中...'
})
}
login({
username:'admin',
password:'123456'
}).then(res=>{
if(res.success){
// 登录成功
}
})
或者
const login = {
url: '/api/login',
method: 'POST',
data: {
username:'admin',
password:'123456'
},
loadingText: '登录中...'
}
sketionUtil.sendRequest(login).then(res=>{
if(res.success){
// 登录成功
}
})
另一种用法
sketion-http
可以规范一次请求的过程与结果,它不仅能规范新的,还能规范旧的 比如一些老旧的项目,创建时没能做好请求封装,可能loading需要每次都手动展示和取消,请求结果也每次都 需要从层层嵌套中取出,错误信息也需要手动抛出。这种情况,sketion-http
可以完美解决。老代码示例:
// 创建的api const login = axios({ url:'/api/login', data:{ username:'admin', password:'123456' }, method: 'POST', }) // 使用 // 调用前展示 loading login().then(res=>{ // 判断网络状态码 if(res.status === 200){ // 判断接口是否调用成功 if(res.data.code === 0){ // 登录成功 }else{ // 展示接口报错 } }else{ // 展示网络错误 } }).catch(e=>{ // 展示网络错误或逻辑错误 }).finally(()=>{ // 调用完关闭loading })
这样的api调用让人每次都心力憔悴
使用
sketionUtil.embraceRequest
方法const login = axios({ url:'/api/login', data:{ username:'admin', password:'123456' }, method: 'POST', }) sketionUtil.embraceRequest(login).then(res=>{ if(res.success){ // 登录成功 } })
embraceRequest
可以极大的减轻你的心智负担,将有限的精力集中到业务层面上去,它接收两个参数embraceRequest: (request: Promise<any>, opts?: Q | undefined) => Promise<R>;
第一个参数是一个
promise
对象,embraceRequest
会劫持这个promise
来实现流程标准化, 第二个参数是一个SketionRequestOptions
类型的对象,可以规定这次请求是否展示加载和警告信息等。
文档
sketion-http
的使用方式如上所述,配置好后只需了解SketionRequestOptions
属性即可
interface SketionRequestOptions {
rejectError?: boolean;
}
| 属性名 | 类型 | 默认值 | 说明 | | ----------- | ------- | ------ | ---------------------------- | | rejectError | boolean | false | 是否以reject方式返回报错信息 |