Compare commits
10 Commits
dbb74eab66
...
a259962a55
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a259962a55 | ||
|
|
cf343695d0 | ||
|
|
0b837e88a3 | ||
|
|
a8898b09e0 | ||
|
|
1e7f329ce9 | ||
|
|
1caaaab1af | ||
|
|
11404bb4bb | ||
|
|
dbcccbaa78 | ||
|
|
a1033806fe | ||
|
|
71fa0bdd9d |
14
README.md
14
README.md
@@ -482,4 +482,18 @@ weRequest.init({
|
||||
},
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
### 回调的success和complete的时序怎么和wx.request的时序不一致?
|
||||
|
||||
早期请求库引入promise能力时,由于代码缺陷导致success/complete执行的顺序与官方wx.request的success/complete执行顺序是相反的。(正确的顺序应该是先执行success回调,再执行complete回调)。
|
||||
由于这个问题存在比较久且很细微,可能大部分业务在使用的时候也没有太留意。
|
||||
请求库在`1.7.5`版本中对其进行了修复,但是为了不影响之前使用了本库的业务,所以增加了一个配置项`isFixSuccessCompleteTiming`,用于指定修复这个问题。
|
||||
若不配置这个项,则仍保持这个错误的回调顺序,若业务希望顺序跟官方保持一致,则需要在初始化时配置这个配置项,示例如下:
|
||||
```javascript
|
||||
weRequest.init({
|
||||
// ...
|
||||
isFixSuccessCompleteTiming: true
|
||||
// 省略其他配置项...
|
||||
})
|
||||
```
|
||||
10
build/interface.d.ts
vendored
10
build/interface.d.ts
vendored
@@ -1,6 +1,7 @@
|
||||
/// <reference types="miniprogram-api-typings" />
|
||||
export declare type Request = <TResp>(options: IRequestOption) => Promise<TResp>;
|
||||
export declare type IAnyObject = WechatMiniprogram.IAnyObject;
|
||||
/// <reference types="miniprogram-api-typings" />
|
||||
export type Request = <TResp>(options: IRequestOption) => Promise<TResp>;
|
||||
export type IAnyObject = WechatMiniprogram.IAnyObject;
|
||||
export interface IInitOption {
|
||||
codeToSession: ICodeToSessionOptions;
|
||||
sessionName: string;
|
||||
@@ -23,6 +24,11 @@ export interface IInitOption {
|
||||
doNotUseQueryString?: boolean;
|
||||
errorHandler?: Function | null;
|
||||
beforeSend?: Function | null;
|
||||
systemErrorHandler?: Function | null;
|
||||
backupDomainList?: IAnyObject;
|
||||
backupDomainEnableCallback?: Function;
|
||||
domainChangeTrigger?: Function;
|
||||
isFixSuccessCompleteTiming?: boolean;
|
||||
}
|
||||
export interface ICodeToSessionOptions {
|
||||
url: string;
|
||||
|
||||
2
build/module/requestHandler.d.ts
vendored
2
build/module/requestHandler.d.ts
vendored
@@ -2,9 +2,11 @@ import { IRequestOption, IUploadFileOption } from "../interface";
|
||||
declare function format(originUrl: string): string;
|
||||
declare function request<TResp>(obj: IRequestOption): Promise<TResp>;
|
||||
declare function uploadFile(obj: IUploadFileOption): any;
|
||||
declare function enableBackupDomain(url?: string): void;
|
||||
declare const _default: {
|
||||
format: typeof format;
|
||||
request: typeof request;
|
||||
uploadFile: typeof uploadFile;
|
||||
enableBackupDomain: typeof enableBackupDomain;
|
||||
};
|
||||
export default _default;
|
||||
|
||||
3
build/module/sessionManager.d.ts
vendored
3
build/module/sessionManager.d.ts
vendored
@@ -1,7 +1,6 @@
|
||||
import { IRequestOption, IUploadFileOption } from "../interface";
|
||||
declare function setSession(session: string): void;
|
||||
declare function delSession(): void;
|
||||
declare function main(relatedRequestObj?: IRequestOption | IUploadFileOption): Promise<void>;
|
||||
declare function main(): Promise<void>;
|
||||
declare const _default: {
|
||||
main: typeof main;
|
||||
setSession: typeof setSession;
|
||||
|
||||
4
build/util/url.d.ts
vendored
4
build/util/url.d.ts
vendored
@@ -1,5 +1,9 @@
|
||||
declare function setParams(url: string | undefined, params: object): string;
|
||||
declare function replaceDomain(url?: string): string;
|
||||
declare function isInBackupDomainList(url?: string): boolean;
|
||||
declare const _default: {
|
||||
setParams: typeof setParams;
|
||||
replaceDomain: typeof replaceDomain;
|
||||
isInBackupDomainList: typeof isInBackupDomainList;
|
||||
};
|
||||
export default _default;
|
||||
|
||||
File diff suppressed because one or more lines are too long
4
build/weRequest.min.js
vendored
4
build/weRequest.min.js
vendored
File diff suppressed because one or more lines are too long
12764
package-lock.json
generated
12764
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "we-request",
|
||||
"version": "1.6.7",
|
||||
"version": "1.8.1",
|
||||
"description": "本工具通过拓展小程序的wx.request,让开发者通过简单的配置,实现自动管理登录态等功能",
|
||||
"keywords": [
|
||||
"登录态",
|
||||
@@ -44,7 +44,7 @@
|
||||
"ts-loader": "^5.3.1",
|
||||
"tslint": "^5.12.0",
|
||||
"tslint-config-prettier": "^1.17.0",
|
||||
"typescript": "^3.7.4",
|
||||
"typescript": "^4.9.5",
|
||||
"webpack": "^4.28.0",
|
||||
"webpack-cli": "^3.3.12"
|
||||
},
|
||||
|
||||
@@ -4,7 +4,6 @@ import { IInitOption } from '../interface'
|
||||
|
||||
export default (params: IInitOption) => {
|
||||
Object.assign(config, params);
|
||||
console.log(config.errorTitle);
|
||||
try {
|
||||
status.session = wx.getStorageSync(config.sessionName!) || '';
|
||||
} catch (e) {}
|
||||
|
||||
@@ -54,6 +54,16 @@ export interface IInitOption {
|
||||
errorHandler?: Function | null;
|
||||
/* 请求发送前,提供hook给开发者自定义修改发送内容 */
|
||||
beforeSend?: Function | null;
|
||||
/* 自定义系统错误处理函数 */
|
||||
systemErrorHandler?: Function | null;
|
||||
/* 备用域名 */
|
||||
backupDomainList?: IAnyObject;
|
||||
/* 备用域名启用时回调函数 */
|
||||
backupDomainEnableCallback?: Function;
|
||||
/* 是否需要启用备用域名 */
|
||||
domainChangeTrigger?: Function;
|
||||
/* 是否修复请求的success/complete的时序问题,详见README的QA部分 */
|
||||
isFixSuccessCompleteTiming?: boolean;
|
||||
}
|
||||
|
||||
export interface ICodeToSessionOptions{
|
||||
|
||||
@@ -5,9 +5,11 @@ import { IRequestOption, IUploadFileOption } from "../interface";
|
||||
function systemError(obj: IRequestOption | IUploadFileOption, res: WechatMiniprogram.GeneralCallbackResult) {
|
||||
if (typeof obj.fail === "function") {
|
||||
obj.fail(res);
|
||||
} else if (typeof config.systemErrorHandler === 'function') {
|
||||
config.systemErrorHandler(res);
|
||||
} else {
|
||||
const retry = () => request(obj).then(obj._resolve).catch(obj._reject);
|
||||
doError("", res.errMsg, retry);
|
||||
doError("", "", retry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,9 @@ function initializeRequestObj(obj: IRequestOption) {
|
||||
obj.url = url.setParams(obj.url, gd);
|
||||
}
|
||||
|
||||
// 备用域名逻辑
|
||||
obj.url = url.replaceDomain(obj.url);
|
||||
|
||||
durationReporter.start(obj);
|
||||
|
||||
return obj;
|
||||
@@ -125,6 +128,9 @@ function initializeUploadFileObj(obj: IUploadFileOption) {
|
||||
obj.url = url.setParams(obj.url, gd);
|
||||
}
|
||||
|
||||
// 备用域名逻辑
|
||||
obj.url = url.replaceDomain(obj.url);
|
||||
|
||||
durationReporter.start(obj);
|
||||
|
||||
return obj;
|
||||
@@ -141,6 +147,10 @@ function getGlobalData() {
|
||||
}
|
||||
|
||||
function doRequest(obj: IRequestOption) {
|
||||
// 真正发请求时,再次判断一次是否有登陆态
|
||||
if(!status.session) {
|
||||
return request(obj) as Promise<WechatMiniprogram.RequestSuccessCallbackResult>;
|
||||
}
|
||||
obj = initializeRequestObj(obj);
|
||||
if (obj.reLoginCount === 0 && typeof config.beforeSend === "function") {
|
||||
obj = config.beforeSend(obj, status.session);
|
||||
@@ -152,14 +162,32 @@ function doRequest(obj: IRequestOption) {
|
||||
return resolve(res);
|
||||
},
|
||||
fail(res) {
|
||||
// 如果主域名不可用,且配置了备份域名,且本次请求未使用备份域名
|
||||
if ((config.domainChangeTrigger && config.domainChangeTrigger(res)) && url.isInBackupDomainList(obj.url)) {
|
||||
// 开启备份域名
|
||||
enableBackupDomain(obj.url);
|
||||
// 重试一次
|
||||
return doRequest(obj).then((res)=> resolve(res));
|
||||
}
|
||||
return reject({ type: 'system-error', res });
|
||||
},
|
||||
complete() {
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
if (config.isFixSuccessCompleteTiming) {
|
||||
setTimeout(()=>{
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
}
|
||||
}, 0)
|
||||
} else {
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -167,6 +195,10 @@ function doRequest(obj: IRequestOption) {
|
||||
}
|
||||
|
||||
function doUploadFile(obj: IUploadFileOption) {
|
||||
// 真正发请求时,再次判断一次是否有登陆态
|
||||
if(!status.session) {
|
||||
return uploadFile(obj) as Promise<WechatMiniprogram.UploadFileSuccessCallbackResult>;
|
||||
}
|
||||
obj = initializeUploadFileObj(obj);
|
||||
if (obj.reLoginCount === 0 && typeof config.beforeSend === "function") {
|
||||
obj = config.beforeSend(obj, status.session);
|
||||
@@ -178,14 +210,32 @@ function doUploadFile(obj: IUploadFileOption) {
|
||||
return resolve(res);
|
||||
},
|
||||
fail(res) {
|
||||
// 如果主域名不可用,且配置了备份域名,且本次请求未使用备份域名
|
||||
if ((config.domainChangeTrigger && config.domainChangeTrigger(res)) && url.isInBackupDomainList(obj.url)) {
|
||||
// 开启备份域名
|
||||
enableBackupDomain(obj.url);
|
||||
// 重试一次
|
||||
return doUploadFile(obj).then((res)=> resolve(res));
|
||||
}
|
||||
return reject({ type: 'system-error', res });
|
||||
},
|
||||
complete() {
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
if (config.isFixSuccessCompleteTiming) {
|
||||
setTimeout(()=>{
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
}
|
||||
}, 0)
|
||||
} else {
|
||||
if (typeof obj.complete === "function") {
|
||||
obj.complete();
|
||||
}
|
||||
if (obj.showLoading) {
|
||||
loading.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -208,7 +258,7 @@ function request<TResp>(obj: IRequestOption): Promise<TResp> {
|
||||
cacheManager.get(obj);
|
||||
}
|
||||
|
||||
sessionManager.main(obj).then(() => {
|
||||
sessionManager.main().then(() => {
|
||||
return doRequest(obj)
|
||||
}).then((res: WechatMiniprogram.RequestSuccessCallbackResult) => {
|
||||
let response = responseHandler.responseForRequest(res, obj);
|
||||
@@ -233,7 +283,7 @@ function uploadFile(obj: IUploadFileOption): any {
|
||||
}
|
||||
}
|
||||
|
||||
sessionManager.main(obj).then(() => {
|
||||
sessionManager.main().then(() => {
|
||||
return doUploadFile(obj)
|
||||
}).then((res: WechatMiniprogram.UploadFileSuccessCallbackResult) => {
|
||||
let response = responseHandler.responseForUploadFile(res, obj);
|
||||
@@ -246,8 +296,18 @@ function uploadFile(obj: IUploadFileOption): any {
|
||||
})
|
||||
}
|
||||
|
||||
function enableBackupDomain(url: string = "") {
|
||||
if (!status.isEnableBackupDomain) {
|
||||
status.isEnableBackupDomain = true;
|
||||
if (typeof config.backupDomainEnableCallback === 'function') {
|
||||
config.backupDomainEnableCallback(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
format,
|
||||
request,
|
||||
uploadFile
|
||||
uploadFile,
|
||||
enableBackupDomain
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import status from '../store/status'
|
||||
import config from '../store/config'
|
||||
import errorHandler from './errorHandler'
|
||||
import durationReporter from './durationReporter'
|
||||
import requestHandler from './requestHandler'
|
||||
import loading from '../util/loading'
|
||||
import request from '../api/request'
|
||||
import { IRequestOption, IUploadFileOption } from "../interface";
|
||||
import url from '../util/url'
|
||||
import { IErrorObject } from "../interface"
|
||||
|
||||
/* 生命周期内只做一次的checkSession */
|
||||
let checkSessionPromise: any = null;
|
||||
@@ -156,6 +155,9 @@ async function code2Session(code: string) {
|
||||
obj = config.beforeSend(obj);
|
||||
}
|
||||
|
||||
// 备用域名逻辑
|
||||
obj.url = url.replaceDomain(obj.url);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let start = new Date().getTime();
|
||||
wx.request({
|
||||
@@ -174,33 +176,24 @@ async function code2Session(code: string) {
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
if (typeof s === 'string') {
|
||||
status.session = s;
|
||||
// 换回来的session,不需要再checkSession
|
||||
config.doNotCheckSession = true;
|
||||
// 如果有设置本地session过期时间
|
||||
if (config.sessionExpireTime && config.sessionExpireKey) {
|
||||
status.sessionExpire = new Date().getTime() + config.sessionExpireTime;
|
||||
wx.setStorage({
|
||||
key: config.sessionExpireKey,
|
||||
data: String(status.sessionExpire)
|
||||
})
|
||||
}
|
||||
wx.setStorage({
|
||||
key: config.sessionName,
|
||||
data: status.session
|
||||
});
|
||||
if (typeof s === 'string' && s) {
|
||||
setSession(s);
|
||||
return resolve(s);
|
||||
} else {
|
||||
return reject(errorHandler.getErrorMsg(res));
|
||||
return reject({type: "logic-error", res});
|
||||
}
|
||||
} else {
|
||||
return reject({type: "http-error", res});
|
||||
}
|
||||
},
|
||||
complete() {
|
||||
},
|
||||
fail: (res) => {
|
||||
// 如果主域名不可用,且配置了备份域名,且本次请求未使用备份域名
|
||||
if ((config.domainChangeTrigger && config.domainChangeTrigger(res)) && url.isInBackupDomainList(obj.url)) {
|
||||
// 开启备份域名
|
||||
requestHandler.enableBackupDomain(obj.url);
|
||||
// 重试一次
|
||||
return code2Session(code).then((res)=> resolve(res));
|
||||
}
|
||||
return reject({type: "system-error", res});
|
||||
}
|
||||
})
|
||||
@@ -221,23 +214,14 @@ function delSession() {
|
||||
}
|
||||
}
|
||||
|
||||
function main(relatedRequestObj?: IRequestOption | IUploadFileOption) {
|
||||
function main() {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
let retry = !relatedRequestObj
|
||||
// 如果没有关联的请求,重试即调用自身
|
||||
? () => main().then(resolve).catch(reject)
|
||||
// 如果有关联的请求,重试即调用所关联的请求
|
||||
: () => request(relatedRequestObj).then(relatedRequestObj._resolve).catch(relatedRequestObj._reject);
|
||||
return checkLogin().then(() => {
|
||||
return config.doNotCheckSession ? Promise.resolve() : checkSession()
|
||||
}, ({title, content}) => {
|
||||
errorHandler.doError(title, content, retry);
|
||||
return reject({title, content});
|
||||
}).then(() => {
|
||||
return resolve();
|
||||
}, ({title, content})=> {
|
||||
errorHandler.doError(title, content, retry);
|
||||
return reject({title, content});
|
||||
}).catch((e: IErrorObject) => {
|
||||
return reject(e);
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -30,7 +30,19 @@ const defaultConfig: IInitOption = {
|
||||
// 自定义错误处理函数
|
||||
errorHandler: null,
|
||||
// 请求发送前,提供hook给开发者自定义修改发送内容
|
||||
beforeSend: null
|
||||
beforeSend: null,
|
||||
// 自定义系统错误处理函数(网络错误)
|
||||
systemErrorHandler: null,
|
||||
// 默认降级处理函数
|
||||
domainChangeTrigger: (res: WechatMiniprogram.GeneralCallbackResult) => {
|
||||
// -101 和 -102 默认自动降级
|
||||
if ((res?.errMsg?.indexOf('CONNECTION_REFUSED') >= 0 || res?.errMsg?.indexOf('ERR_CONNECTION_RESET') >= 0)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
// 是否修复请求的success/complete的时序问题,详见README的QA部分
|
||||
isFixSuccessCompleteTiming: false
|
||||
};
|
||||
|
||||
export default defaultConfig;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export default {
|
||||
session: '' as string,
|
||||
// session过期的时间点
|
||||
sessionExpire: Infinity as number
|
||||
sessionExpire: Infinity as number,
|
||||
// 是否启用备用域名
|
||||
isEnableBackupDomain: false
|
||||
} as any
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import config from '../store/config'
|
||||
import status from '../store/status'
|
||||
|
||||
function setParams(url: string = "", params: object) {
|
||||
const queryStringIndex: number = url.indexOf("?");
|
||||
let kvp: any = {};
|
||||
@@ -25,6 +28,33 @@ function setParams(url: string = "", params: object) {
|
||||
}
|
||||
}
|
||||
|
||||
function replaceDomain(url: string = "") {
|
||||
if (status.isEnableBackupDomain && config.backupDomainList && typeof config.backupDomainList === 'object') {
|
||||
for(const origin in config.backupDomainList) {
|
||||
if (url.indexOf(origin) >= 0) {
|
||||
url = url.replace(origin, config.backupDomainList[origin]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function isInBackupDomainList(url: string = "") {
|
||||
let res = false;
|
||||
if (config.backupDomainList && typeof config.backupDomainList === 'object') {
|
||||
for(const origin in config.backupDomainList) {
|
||||
if (url.indexOf(origin) >= 0) {
|
||||
res = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
export default {
|
||||
setParams
|
||||
setParams,
|
||||
replaceDomain,
|
||||
isInBackupDomainList
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user