@zwa73/utils 1.0.78 → 1.0.80
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/QuickFunction.d.ts +5 -5
- package/dist/QuickFunction.js +2 -2
- package/dist/UtilFunctions.js +10 -9
- package/dist/UtilInterfaces.d.ts +7 -2
- package/dist/UtilSymbol.d.ts +3 -0
- package/dist/UtilSymbol.js +3 -1
- package/dist/test/repeatTest.d.ts +1 -0
- package/dist/test/repeatTest.js +29 -0
- package/package.json +1 -1
- package/src/QuickFunction.ts +7 -6
- package/src/UtilFunctions.ts +11 -10
- package/src/UtilInterfaces.ts +12 -3
- package/src/UtilSymbol.ts +3 -0
- package/src/test/repeatTest.ts +29 -0
- package/test/test.bat +2 -0
- package/test/test.js +37 -0
package/dist/QuickFunction.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { ExtractOutcome, Keyable, Outcome } from "./UtilInterfaces";
|
|
2
|
-
/**创建一个
|
|
1
|
+
import { ExtractOutcome, Keyable, Outcome, UnionToIntersection } from "./UtilInterfaces";
|
|
2
|
+
/**创建一个Outcome */
|
|
3
3
|
export declare function outcome<K extends Keyable, V>(key: K, value: V): Outcome<K, V>;
|
|
4
|
-
|
|
4
|
+
/**处理联合值
|
|
5
5
|
* @param t - 目标值
|
|
6
6
|
* @param procObj - 所有可能的id组成的处理函数映射
|
|
7
7
|
* @returns 任意处理函数的返回值
|
|
8
8
|
*/
|
|
9
|
-
export declare function match<T extends Keyable | Outcome<Keyable, unknown>, P extends (T extends Keyable ? {
|
|
9
|
+
export declare function match<T extends Keyable | Outcome<Keyable, unknown>, P extends UnionToIntersection<(T extends Keyable ? {
|
|
10
10
|
[K in T]: (k: K) => unknown;
|
|
11
11
|
} : T extends Outcome<Keyable, unknown> ? {
|
|
12
12
|
[K in T['status']]: (k: K, v: ExtractOutcome<T, K>['result']) => unknown;
|
|
13
|
-
} : never)
|
|
13
|
+
} : never)>>(t: T, procObj: P): P extends Record<any, (...args: any) => any> ? {
|
|
14
14
|
[K in keyof P]: ReturnType<P[K]>;
|
|
15
15
|
}[keyof P] : never;
|
package/dist/QuickFunction.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.match = exports.outcome = void 0;
|
|
4
|
-
/**创建一个
|
|
4
|
+
/**创建一个Outcome */
|
|
5
5
|
function outcome(key, value) {
|
|
6
6
|
return { status: key, result: value };
|
|
7
7
|
}
|
|
8
8
|
exports.outcome = outcome;
|
|
9
|
-
|
|
9
|
+
/**处理联合值
|
|
10
10
|
* @param t - 目标值
|
|
11
11
|
* @param procObj - 所有可能的id组成的处理函数映射
|
|
12
12
|
* @returns 任意处理函数的返回值
|
package/dist/UtilFunctions.js
CHANGED
|
@@ -131,7 +131,7 @@ class UtilFunc {
|
|
|
131
131
|
repeatTime *= 1000;
|
|
132
132
|
//验证处理函数
|
|
133
133
|
if (verifyFn === undefined)
|
|
134
|
-
verifyFn = () => UtilSymbol_1.
|
|
134
|
+
verifyFn = () => UtilSymbol_1.Success;
|
|
135
135
|
//进行中的请求
|
|
136
136
|
const plist = [];
|
|
137
137
|
//开始处理
|
|
@@ -142,10 +142,11 @@ class UtilFunc {
|
|
|
142
142
|
//如果 plist 中当前下标的任务还未创建 则 创建当前任务
|
|
143
143
|
if (plist.length < i + 1) {
|
|
144
144
|
plist.push(UtilFunc.timelimitPromise(async () => {
|
|
145
|
+
const index = i;
|
|
145
146
|
const result = await procFn();
|
|
146
147
|
const stat = await verifyFn(result);
|
|
147
|
-
return { result, stat, index
|
|
148
|
-
}));
|
|
148
|
+
return { result, stat, index };
|
|
149
|
+
}, hasRepeatTime ? repeatTime : undefined));
|
|
149
150
|
}
|
|
150
151
|
//等待任意任务 或当前计时器完成
|
|
151
152
|
const currObj = await Promise.race([...plist]);
|
|
@@ -163,7 +164,7 @@ class UtilFunc {
|
|
|
163
164
|
//路由请求状态
|
|
164
165
|
const postresult = currObj.result;
|
|
165
166
|
const result = (0, QuickFunction_1.match)(postresult.stat, {
|
|
166
|
-
[UtilSymbol_1.
|
|
167
|
+
[UtilSymbol_1.Success]() {
|
|
167
168
|
UtilLogger_1.SLogger.info(`第 ${postresult.index + 1} 次 repeatPromise 成功`);
|
|
168
169
|
//非当前
|
|
169
170
|
if (postresult.index != i)
|
|
@@ -208,18 +209,18 @@ class UtilFunc {
|
|
|
208
209
|
static timelimitPromise(func, timeLimit) {
|
|
209
210
|
return new Promise((reslove) => {
|
|
210
211
|
let clearTimer = null;
|
|
211
|
-
|
|
212
|
+
const procer = (async () => await func())();
|
|
212
213
|
const procerP = new Promise(async (resolve) => {
|
|
213
|
-
const res = await
|
|
214
|
+
const res = await procer;
|
|
215
|
+
resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Completed, res));
|
|
214
216
|
if (clearTimer)
|
|
215
217
|
clearTimer();
|
|
216
|
-
resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Completed, res));
|
|
217
218
|
});
|
|
218
219
|
const timerP = timeLimit
|
|
219
220
|
? new Promise((resolve) => {
|
|
220
|
-
const timer = setTimeout(() => resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Timeout,
|
|
221
|
+
const timer = setTimeout(() => resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Timeout, procer)), timeLimit); //无限制则无限时间
|
|
221
222
|
clearTimer = () => {
|
|
222
|
-
resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Timeout,
|
|
223
|
+
resolve((0, QuickFunction_1.outcome)(UtilSymbol_1.Timeout, procer));
|
|
223
224
|
clearInterval(timer);
|
|
224
225
|
};
|
|
225
226
|
})
|
package/dist/UtilInterfaces.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Failed, Success, Terminated } from "./UtilSymbol";
|
|
2
2
|
/**可以序列化为JSON文件的对象 */
|
|
3
3
|
export type JToken = JObject | JArray | JValue | IJData;
|
|
4
4
|
/**在stringify输出时 undefine 会被转为 null */
|
|
@@ -32,6 +32,11 @@ export type FixedLengthTuple<T, N extends number, R extends unknown[] = []> = R[
|
|
|
32
32
|
* (string&String)
|
|
33
33
|
*/
|
|
34
34
|
export type AnyString = (string & {});
|
|
35
|
+
/**联合类型转为交叉类型
|
|
36
|
+
* 将联合类型映射为联合函数
|
|
37
|
+
* 再取得可以传递给任意联合函数的类型
|
|
38
|
+
*/
|
|
39
|
+
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
35
40
|
/**创建一个新的类型,这个新的类型包含了基础类型 B 的所有属性,
|
|
36
41
|
* 以及一个名为 K[N] 类型为 T 的新属性。
|
|
37
42
|
* 所有 K 中非 K[N] 的其他属性都是可选的并且不能被赋值(因为它们的类型是 never)。
|
|
@@ -56,7 +61,7 @@ export type ExclusiveJObject<B extends JObject, T extends JToken, K extends stri
|
|
|
56
61
|
* 终止 将直接返回 null
|
|
57
62
|
* 失败 将重试
|
|
58
63
|
*/
|
|
59
|
-
export type PromiseStat =
|
|
64
|
+
export type PromiseStat = Success | Failed | Terminated;
|
|
60
65
|
/**promise验证函数 */
|
|
61
66
|
export type PromiseVerifyFn<T> = (obj: T) => Promise<PromiseStat> | PromiseStat;
|
|
62
67
|
/**类型中任意函数的字符串名称 */
|
package/dist/UtilSymbol.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**完成 */
|
|
2
2
|
export declare const Completed: unique symbol;
|
|
3
3
|
export type Completed = typeof Completed;
|
|
4
|
+
/**成功 */
|
|
5
|
+
export declare const Success: unique symbol;
|
|
6
|
+
export type Success = typeof Success;
|
|
4
7
|
/**失败 */
|
|
5
8
|
export declare const Failed: unique symbol;
|
|
6
9
|
export type Failed = typeof Failed;
|
package/dist/UtilSymbol.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Timeout = exports.None = exports.Terminated = exports.Failed = exports.Completed = void 0;
|
|
3
|
+
exports.Timeout = exports.None = exports.Terminated = exports.Failed = exports.Success = exports.Completed = void 0;
|
|
4
4
|
/**完成 */
|
|
5
5
|
exports.Completed = Symbol("Completed");
|
|
6
|
+
/**成功 */
|
|
7
|
+
exports.Success = Symbol("Success");
|
|
6
8
|
/**失败 */
|
|
7
9
|
exports.Failed = Symbol("Failed");
|
|
8
10
|
/**终止 */
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const __1 = require("..");
|
|
4
|
+
// 模拟的异步函数,有一定几率失败
|
|
5
|
+
async function mockAsyncFunction() {
|
|
6
|
+
return new Promise((resolve, reject) => {
|
|
7
|
+
setTimeout(() => {
|
|
8
|
+
Math.random() > 0.5 ? resolve("Success") : reject("Failure");
|
|
9
|
+
}, Math.random() % 2000);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
// 验证函数,只有当结果为 "Success" 时才认为成功
|
|
13
|
+
function mockVerifyFunction(result) {
|
|
14
|
+
return result === "Success" ? __1.Success : __1.Failed;
|
|
15
|
+
}
|
|
16
|
+
// 测试 repeatPromise 函数
|
|
17
|
+
__1.UtilFunc.repeatPromise(mockAsyncFunction, mockVerifyFunction, 3, 10)
|
|
18
|
+
.then(result => {
|
|
19
|
+
console.log("then");
|
|
20
|
+
if (result === null) {
|
|
21
|
+
console.log("全部超时");
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log("成功:", result);
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
.catch(err => {
|
|
28
|
+
console.error("出现错误", err);
|
|
29
|
+
});
|
package/package.json
CHANGED
package/src/QuickFunction.ts
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import { ExtractOutcome, Keyable, Outcome } from "./UtilInterfaces";
|
|
1
|
+
import { ExtractOutcome, Keyable, Outcome, UnionToIntersection } from "./UtilInterfaces";
|
|
2
2
|
|
|
3
|
-
/**创建一个
|
|
3
|
+
/**创建一个Outcome */
|
|
4
4
|
export function outcome<K extends Keyable,V> (key:K,value:V):Outcome<K,V>{
|
|
5
5
|
return {status:key,result:value}
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
/**处理联合值
|
|
9
10
|
* @param t - 目标值
|
|
10
11
|
* @param procObj - 所有可能的id组成的处理函数映射
|
|
11
12
|
* @returns 任意处理函数的返回值
|
|
12
13
|
*/
|
|
13
14
|
export function match<
|
|
14
15
|
T extends Keyable | Outcome<Keyable, unknown>,
|
|
15
|
-
P extends (T extends Keyable
|
|
16
|
+
P extends UnionToIntersection<(T extends Keyable
|
|
16
17
|
? {[K in T]:(k:K)=>unknown}
|
|
17
18
|
: T extends Outcome<Keyable,unknown>
|
|
18
|
-
? {[K in T['status']]:(k:K,v:ExtractOutcome<T,K>['result'])=>unknown}
|
|
19
|
-
: never)
|
|
19
|
+
? { [K in T['status']] : (k:K,v:ExtractOutcome<T,K>['result'])=>unknown }
|
|
20
|
+
: never)>>
|
|
20
21
|
(t:T, procObj:P):
|
|
21
22
|
P extends Record<any,(...args:any)=>any>
|
|
22
23
|
? {[K in keyof P]: ReturnType<P[K]>}[keyof P]
|
package/src/UtilFunctions.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as crypto from "crypto";
|
|
|
2
2
|
import { ComposedClass, ComposedMixinable, ExtractOutcome, IJData, JObject, JToken, Keyable, Mixinable, Outcome, PromiseStat, PromiseVerifyFn } from "@src/UtilInterfaces";
|
|
3
3
|
import * as cp from "child_process";
|
|
4
4
|
import { SLogger } from "@src/UtilLogger";
|
|
5
|
-
import { Completed, Failed, None, Terminated, Timeout } from "./UtilSymbol";
|
|
5
|
+
import { Completed, Failed, None, Success, Terminated, Timeout } from "./UtilSymbol";
|
|
6
6
|
import { match, outcome } from "./QuickFunction";
|
|
7
7
|
import { LogTimeAsync } from "./UtilDecorators";
|
|
8
8
|
|
|
@@ -160,7 +160,7 @@ static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:PromiseVerifyFn<T>
|
|
|
160
160
|
|
|
161
161
|
//验证处理函数
|
|
162
162
|
if(verifyFn===undefined)
|
|
163
|
-
verifyFn = ()=>
|
|
163
|
+
verifyFn = ()=>Success;
|
|
164
164
|
|
|
165
165
|
//进行中的请求
|
|
166
166
|
const plist:Promise<
|
|
@@ -177,10 +177,11 @@ static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:PromiseVerifyFn<T>
|
|
|
177
177
|
//如果 plist 中当前下标的任务还未创建 则 创建当前任务
|
|
178
178
|
if(plist.length<i+1){
|
|
179
179
|
plist.push(UtilFunc.timelimitPromise<ProcessingPromise<T>>(async ()=>{
|
|
180
|
+
const index = i;
|
|
180
181
|
const result = await procFn();
|
|
181
182
|
const stat = await verifyFn!(result);
|
|
182
|
-
return {result, stat, index
|
|
183
|
-
}));
|
|
183
|
+
return {result, stat, index}
|
|
184
|
+
},hasRepeatTime?repeatTime:undefined));
|
|
184
185
|
}
|
|
185
186
|
|
|
186
187
|
//等待任意任务 或当前计时器完成
|
|
@@ -201,7 +202,7 @@ static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:PromiseVerifyFn<T>
|
|
|
201
202
|
//路由请求状态
|
|
202
203
|
const postresult = currObj.result;
|
|
203
204
|
const result = match(postresult.stat,{
|
|
204
|
-
[
|
|
205
|
+
[Success](){
|
|
205
206
|
SLogger.info(`第 ${postresult.index+1} 次 repeatPromise 成功`);
|
|
206
207
|
//非当前
|
|
207
208
|
if(postresult.index!=i)
|
|
@@ -247,22 +248,22 @@ static timelimitPromise<T>
|
|
|
247
248
|
(func:()=>Promise<T>|T,timeLimit?:number):Promise<CompleteCome<T>|TimeoutCome<T>>{
|
|
248
249
|
return new Promise<CompleteCome<T>|TimeoutCome<T>>((reslove)=>{
|
|
249
250
|
let clearTimer:(()=>void)| null = null;
|
|
250
|
-
|
|
251
|
+
const procer = (async ()=>await func())();
|
|
251
252
|
|
|
252
253
|
const procerP = new Promise<CompleteCome<T>>(async (resolve)=>{
|
|
253
|
-
const res = await
|
|
254
|
+
const res = await procer;
|
|
255
|
+
resolve(outcome(Completed,res));
|
|
254
256
|
if(clearTimer) clearTimer();
|
|
255
|
-
resolve(outcome(Completed,res))
|
|
256
257
|
});
|
|
257
258
|
|
|
258
259
|
const timerP = timeLimit
|
|
259
260
|
? new Promise<TimeoutCome<T>>((resolve)=>{
|
|
260
261
|
const timer = setTimeout(()=>
|
|
261
|
-
resolve(outcome(Timeout,
|
|
262
|
+
resolve(outcome(Timeout,procer))
|
|
262
263
|
,timeLimit);//无限制则无限时间
|
|
263
264
|
|
|
264
265
|
clearTimer = ()=>{
|
|
265
|
-
resolve(outcome(Timeout,
|
|
266
|
+
resolve(outcome(Timeout,procer))
|
|
266
267
|
clearInterval(timer)
|
|
267
268
|
}
|
|
268
269
|
})
|
package/src/UtilInterfaces.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Completed, Failed, Terminated } from "./UtilSymbol";
|
|
1
|
+
import { Completed, Failed, Success, Terminated } from "./UtilSymbol";
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
/**可以序列化为JSON文件的对象 */
|
|
@@ -40,7 +40,16 @@ export type FixedLengthTuple<T, N extends number, R extends unknown[] = []> =
|
|
|
40
40
|
*/
|
|
41
41
|
export type AnyString = (string&{});
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
/**联合类型转为交叉类型
|
|
44
|
+
* 将联合类型映射为联合函数
|
|
45
|
+
* 再取得可以传递给任意联合函数的类型
|
|
46
|
+
*/
|
|
47
|
+
export type UnionToIntersection<U> =
|
|
48
|
+
(U extends any
|
|
49
|
+
? (k: U)=>void
|
|
50
|
+
: never) extends ((k: infer I)=>void)
|
|
51
|
+
? I
|
|
52
|
+
: never
|
|
44
53
|
|
|
45
54
|
/**创建一个新的类型,这个新的类型包含了基础类型 B 的所有属性,
|
|
46
55
|
* 以及一个名为 K[N] 类型为 T 的新属性。
|
|
@@ -71,7 +80,7 @@ export type ExclusiveJObject<B extends JObject,T extends JToken,K extends string
|
|
|
71
80
|
* 终止 将直接返回 null
|
|
72
81
|
* 失败 将重试
|
|
73
82
|
*/
|
|
74
|
-
export type PromiseStat =
|
|
83
|
+
export type PromiseStat = Success|Failed|Terminated;
|
|
75
84
|
/**promise验证函数 */
|
|
76
85
|
export type PromiseVerifyFn<T> = (obj:T)=>Promise<PromiseStat>|PromiseStat;
|
|
77
86
|
|
package/src/UtilSymbol.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
/**完成 */
|
|
2
2
|
export const Completed = Symbol("Completed");
|
|
3
3
|
export type Completed = typeof Completed;
|
|
4
|
+
/**成功 */
|
|
5
|
+
export const Success = Symbol("Success");
|
|
6
|
+
export type Success = typeof Success;
|
|
4
7
|
/**失败 */
|
|
5
8
|
export const Failed = Symbol("Failed");
|
|
6
9
|
export type Failed = typeof Failed;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Completed, Failed, PromiseStat, PromiseVerifyFn, Success, UtilFunc } from "..";
|
|
2
|
+
|
|
3
|
+
// 模拟的异步函数,有一定几率失败
|
|
4
|
+
async function mockAsyncFunction(): Promise<string> {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
setTimeout(() => {
|
|
7
|
+
Math.random() > 0.5 ? resolve("Success") : reject("Failure");
|
|
8
|
+
}, Math.random()%2000);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// 验证函数,只有当结果为 "Success" 时才认为成功
|
|
13
|
+
function mockVerifyFunction(result: string): PromiseStat {
|
|
14
|
+
return result === "Success" ? Success : Failed;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 测试 repeatPromise 函数
|
|
18
|
+
UtilFunc.repeatPromise(mockAsyncFunction, mockVerifyFunction, 3, 10)
|
|
19
|
+
.then(result => {
|
|
20
|
+
console.log("then")
|
|
21
|
+
if (result === null) {
|
|
22
|
+
console.log("全部超时");
|
|
23
|
+
} else {
|
|
24
|
+
console.log("成功:", result);
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
.catch(err => {
|
|
28
|
+
console.error("出现错误", err);
|
|
29
|
+
});
|
package/test/test.bat
ADDED
package/test/test.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const { Completed, Failed, PromiseStat, PromiseVerifyFn, UtilFunc } = require("../dist");
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
let timeList = [21000,5000,1000000]
|
|
5
|
+
let resList = ["Success","Failure","Failure"]
|
|
6
|
+
let index = 0;
|
|
7
|
+
// 模拟的异步函数,有一定几率失败
|
|
8
|
+
async function mockAsyncFunction() {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
|
|
11
|
+
let delay =timeList[index];
|
|
12
|
+
let result = resList[index];
|
|
13
|
+
console.log("延迟: "+delay,"结果: "+result)
|
|
14
|
+
setTimeout(() => {
|
|
15
|
+
resolve(result);
|
|
16
|
+
}, delay);
|
|
17
|
+
index++;
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// 验证函数,只有当结果为 "Success" 时才认为成功
|
|
22
|
+
function mockVerifyFunction(result) {
|
|
23
|
+
return result === "Success" ? Completed : Failed;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// 测试 repeatPromise 函数
|
|
27
|
+
UtilFunc.repeatPromise(mockAsyncFunction, mockVerifyFunction, 3, 10)
|
|
28
|
+
.then(result => {
|
|
29
|
+
if (result === null) {
|
|
30
|
+
console.log("全部超时");
|
|
31
|
+
} else {
|
|
32
|
+
console.log("成功:", result);
|
|
33
|
+
}
|
|
34
|
+
})
|
|
35
|
+
.catch(err => {
|
|
36
|
+
console.error("出现错误", err);
|
|
37
|
+
});
|