@zwa73/utils 1.0.198 → 1.0.200

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.
@@ -31,7 +31,7 @@ type StringifyOpt = Partial<{
31
31
  }>
32
32
 
33
33
  /**Promise重试选项 */
34
- export type RepeatPromiseOpt = Partial<{
34
+ export type PromiseRetries = Partial<{
35
35
  /**重试次数 默认3*/
36
36
  count? :number;
37
37
  /**尝试间隔时间 超过此事件会重新创建新的Promise
@@ -40,6 +40,10 @@ export type RepeatPromiseOpt = Partial<{
40
40
  tryInterval? :number;
41
41
  /**尝试延迟 重新尝试时会先等待此毫秒数 毫秒 默认0*/
42
42
  tryDelay? :number;
43
+ /**是否使用指数回退 默认false 仅在tryDelay被设置时有效 */
44
+ expBackoff?:boolean;
45
+ /**指数回退上限值 默认无限*/
46
+ expBackoffMax?:number;
43
47
  }>
44
48
 
45
49
  type SuccessOut<T> = Outcome<Success,T>;
@@ -57,7 +61,7 @@ type PromiseResult<T> = {
57
61
  };
58
62
 
59
63
  /**完成的重试请求 */
60
- export type RepeatPromiseResult<T> = {
64
+ export type PromiseRetryResult<T> = {
61
65
  completed:T|undefined;
62
66
  /**还未完成的其他Promise 若是验证失败则会返回undefined */
63
67
  pending:Promise<T|undefined>[];
@@ -222,23 +226,23 @@ static getNeverResolvedPromise<T>():Promise<T>{
222
226
 
223
227
  /**重复尝试promise
224
228
  * @async
225
- * @param procFn - 发起函数
226
- * @param verifyFn - 验证函数
227
- * @param opt - 重试参数 默认 延迟:0ms 间隔:180_000ms 重试:3次
229
+ * @param proc - 发起函数
230
+ * @param verify - 验证函数
231
+ * @param retries - 重试参数 默认 延迟:0ms 间隔:180_000ms 重试:3次
228
232
  * @returns 重复结果
229
233
  */
230
- @LogTimeAsync("repeatPromise ",true)
231
- static async repeatPromise<T>(procFn:()=>Promise<T>,verifyFn?:StatusVerifyFn<T>,opt:RepeatPromiseOpt = {}):
232
- Promise<RepeatPromiseResult<T>>{
233
- opt.count = opt.count??3;
234
- opt.tryInterval = opt.tryInterval??180_000;
235
- const {count,tryInterval} = opt;
234
+ @LogTimeAsync("retryPromise ",true)
235
+ static async retryPromise<T>(proc:()=>Promise<T>,verify?:StatusVerifyFn<T>,retries:PromiseRetries = {}):
236
+ Promise<PromiseRetryResult<T>>{
237
+ retries.count = retries.count??3;
238
+ retries.tryInterval = retries.tryInterval??180_000;
239
+ const {count,tryInterval,tryDelay} = retries;
236
240
  /**是否含有超时时间 */
237
241
  const hasRepeatTime = (tryInterval>=5000);
238
242
 
239
243
  //验证处理函数
240
- if(verifyFn===undefined)
241
- verifyFn = ()=>Success;
244
+ if(verify===undefined)
245
+ verify = ()=>Success;
242
246
 
243
247
  //进行中的请求
244
248
  const plist:Promise<
@@ -250,14 +254,19 @@ Promise<RepeatPromiseResult<T>>{
250
254
  try{
251
255
  //根据最大重试次数限制进行循环
252
256
  for(let i=0;i<count;){
253
- if(i>0 && opt.tryDelay) await UtilFunc.sleep(opt.tryDelay);
254
- SLogger.info(`开始第 ${i+1} repeatPromise`);
257
+ if(i>0 && tryDelay){
258
+ const delay = retries.expBackoff
259
+ ? Math.min((Math.pow(2,i)-1)*tryDelay,retries.expBackoffMax??Infinity)
260
+ : tryDelay;
261
+ await UtilFunc.sleep(delay);
262
+ }
263
+ SLogger.info(`开始第 ${i+1} 次 retryPromise`);
255
264
  //如果 plist 中当前下标的任务还未创建 则 创建当前任务
256
265
  if(plist.length<i+1){
257
266
  plist.push(UtilFunc.timelimitPromise<PromiseResult<T>>(async ()=>{
258
267
  const index = i;
259
- const result = await procFn();
260
- const stat = await verifyFn!(result);
268
+ const result = await proc();
269
+ const stat = await verify!(result);
261
270
  return {result, stat, index}
262
271
  },hasRepeatTime?tryInterval:undefined));
263
272
  }
@@ -272,7 +281,7 @@ Promise<RepeatPromiseResult<T>>{
272
281
  const res = await currObj.result;
273
282
  rslove(UtilFunc.outcome(Success,res));
274
283
  })
275
- SLogger.warn(`第 ${i+1} 次 repeatPromise 超时 ${tryInterval} ms 开始重试`);
284
+ SLogger.warn(`第 ${i+1} 次 retryPromise 超时 ${tryInterval} ms 开始重试`);
276
285
  i++;
277
286
  continue;
278
287
  }
@@ -281,14 +290,14 @@ Promise<RepeatPromiseResult<T>>{
281
290
  const postresult = currObj.result;
282
291
  const result = UtilFunc.matchProc(postresult.stat,{
283
292
  [Success](){
284
- SLogger.info(`第 ${postresult.index+1} 次 repeatPromise 成功`);
293
+ SLogger.info(`第 ${postresult.index+1} 次 retryPromise 成功`);
285
294
  //非当前
286
295
  if(postresult.index!=i)
287
296
  SLogger.info(`成功的 promise 非当前 promise 考虑增大重试时间\n当前index: ${i}\n当前重试时间: ${tryInterval}`);
288
297
  return postresult.result;
289
298
  },
290
299
  [Terminated](){
291
- SLogger.warn(`第 ${postresult.index+1} 次 repeatPromise 终止 停止重试`);
300
+ SLogger.warn(`第 ${postresult.index+1} 次 retryPromise 终止 停止重试`);
292
301
  return postresult.result;
293
302
  },
294
303
  [Failed]():None{
@@ -296,12 +305,12 @@ Promise<RepeatPromiseResult<T>>{
296
305
  plist[postresult.index] = UtilFunc.getNeverResolvedPromise();
297
306
  //是当前
298
307
  if(postresult.index==i){
299
- SLogger.warn(`第 ${postresult.index+1} 次 repeatPromise 失败 开始重试`);
308
+ SLogger.warn(`第 ${postresult.index+1} 次 retryPromise 失败 开始重试`);
300
309
  i++;
301
310
  return None;
302
311
  }
303
312
  //非当前
304
- SLogger.warn(`第 ${postresult.index+1} 次 repeatPromise 失败`);
313
+ SLogger.warn(`第 ${postresult.index+1} 次 retryPromise 失败`);
305
314
  return None;
306
315
  },
307
316
  });
@@ -325,7 +334,7 @@ Promise<RepeatPromiseResult<T>>{
325
334
  };
326
335
  }
327
336
  //全部失败或超时则返回 全pending
328
- SLogger.warn(`${count} 次 repeatPromise 尝试均失败`);
337
+ SLogger.warn(`${count} 次 retryPromise 尝试均失败`);
329
338
  return {
330
339
  completed:undefined,
331
340
  pending:plist
@@ -344,7 +353,7 @@ Promise<RepeatPromiseResult<T>>{
344
353
  }),
345
354
  };
346
355
  }catch(err){
347
- SLogger.warn(`repeatPromise 发生意外错误`,err);
356
+ SLogger.warn(`retryPromise 发生意外错误`,err);
348
357
  return {completed:undefined,pending:[]};
349
358
  }
350
359
  }
@@ -822,10 +831,13 @@ static expect<T>(t:T,errLog?:string):Exclude<T,None>{
822
831
  * @param func - 待转换函数
823
832
  * @returns 转换完成的函数
824
833
  */
825
- static eitherize<T extends AnyFunc>(func:T) {
834
+ static eitherize<T extends AnyFunc>(
835
+ func:ReturnType<T> extends Promise<any>
836
+ ? Error&"对异步函数请使用taskEitherize" : T
837
+ ) {
826
838
  return (...args: Parameters<T>) => {
827
839
  try {
828
- const result:ReturnType<T> = func(...args as any);
840
+ const result:ReturnType<T> = (func as T)(...args as any);
829
841
  return UtilFunc.outcome(Success,result);
830
842
  } catch (error) {
831
843
  if(error instanceof Error)
@@ -841,7 +853,7 @@ static eitherize<T extends AnyFunc>(func:T) {
841
853
  static taskEitherize<T extends (...args:any)=>Promise<any>>(func:T) {
842
854
  return async (...args: Parameters<T>) => {
843
855
  try {
844
- const result:Awaited<ReturnType<T>> = await func(...args as any);
856
+ const result:Awaited<ReturnType<T>> = await func(...args);
845
857
  return UtilFunc.outcome(Success,result);
846
858
  } catch (error) {
847
859
  if(error instanceof Error)
@@ -193,7 +193,8 @@ export type WithPrefix<T,P extends string> = {
193
193
  : K
194
194
  ]: T[K]
195
195
  };
196
- /**返回结果
196
+
197
+ /**附带状态的返回结果用于状态返回值的封装
197
198
  * @template K - 类型键值
198
199
  * @template V - 值
199
200
  */
@@ -203,26 +204,23 @@ export type Outcome<K extends Keyable,V> = {
203
204
  /**值 */
204
205
  readonly result:V;
205
206
  }
206
- /**可成功或失败的结果
207
- * @template S - 成功时的结果
208
- * @template F - 失败时的结果
207
+ /**可进行匹配的对象
208
+ * 如果是Outcome则自动处理status
209
209
  */
210
- export type Eithercome<S,F> =
211
- Outcome<Success,S>|Outcome<Failed,F>;
212
-
213
- /**可进行匹配的 outcome或symbol */
214
210
  export type Matchable<T extends Keyable> = T|Outcome<T,unknown>;
215
211
  /**可进行匹配的 outcome或symbol 中的状态类型 */
216
212
  export type MatchableFlag<T> =
217
213
  T extends infer O|Outcome<infer O,unknown>
218
214
  ? O : never;
219
215
 
220
- /**从联合 Outcome 中 根据 id 提取对应 Outcome */
216
+ /**从联合 Outcome 中 根据 K 提取对应 Outcome
217
+ * @template T - 联合Outcome匹配的类型
218
+ * @template K - 所需的状态
219
+ */
221
220
  export type ExtractOutcome<T,K extends Keyable> =
222
221
  T extends Outcome<infer O,unknown>
223
222
  ? O extends Exclude<O,K>
224
- ? never
225
- : T
223
+ ? never : T
226
224
  : never;
227
225
 
228
226
  /**用于辅助解析智能补全的类型