• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

alovajs / alova / #210

08 Oct 2024 07:26AM CUT coverage: 93.734% (-0.09%) from 93.826%
#210

push

github

web-flow
Merge pull request #554 from alovajs/changeset-release/main

ci: release

1608 of 1761 branches covered (91.31%)

Branch coverage included in aggregate %.

9537 of 10129 relevant lines covered (94.16%)

60.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

82.42
/packages/client/src/util/helper.ts
1
import { createAssert } from '@alova/shared/assert';
1✔
2
import { instanceOf, isFn, isNumber, noop, uuid } from '@alova/shared/function';
1✔
3
import { GeneralFn } from '@alova/shared/types';
1✔
4
import {
1✔
5
  clearTimeoutTimer,
1✔
6
  falseValue,
1✔
7
  filterItem,
1✔
8
  forEach,
1✔
9
  nullValue,
1✔
10
  setTimeoutFn,
1✔
11
  undefinedValue
1✔
12
} from '@alova/shared/vars';
1✔
13
import { Method } from 'alova';
1✔
14
import { AlovaMethodHandler } from '~/typings/clienthook';
1✔
15

1✔
16
const referenceList = [] as { id: string; ref: any }[];
1✔
17
/**
1✔
18
 * 获取唯一的引用类型id,如果是非引用类型则返回自身
1✔
19
 * @param 引用类型数据
1✔
20
 * @returns uniqueId
1✔
21
 */
1✔
22
export const getUniqueReferenceId = (reference: any) => {
1✔
23
  const refType = typeof reference;
×
24
  if (!['object', 'function', 'symbol'].includes(refType)) {
×
25
    return reference;
×
26
  }
×
27

×
28
  let existedRef = referenceList.find(({ ref }) => ref === reference);
×
29
  if (!existedRef) {
×
30
    const uniqueId = uuid();
×
31
    existedRef = {
×
32
      id: uniqueId,
×
33
      ref: reference
×
34
    };
×
35
    referenceList.push(existedRef);
×
36
  }
×
37
  return existedRef.id;
×
38
};
×
39

1✔
40
/**
1✔
41
 * 兼容函数,抛出参数
1✔
42
 * @param error 错误
1✔
43
 */
1✔
44
export const throwFn = <T>(error: T) => {
1✔
45
  // eslint-disable-next-line @typescript-eslint/no-throw-literal
4✔
46
  throw error;
4✔
47
};
4✔
48

1✔
49
export const valueObject = <T>(value: T, writable = falseValue) => ({
1✔
50
  value,
×
51
  writable
×
52
});
1✔
53

1✔
54
export function useCallback<Fn extends GeneralFn = GeneralFn>(onCallbackChange: (callbacks: Fn[]) => void = noop) {
2✔
55
  let callbacks: Fn[] = [];
2✔
56

2✔
57
  const setCallback = (fn: Fn) => {
2✔
58
    if (!callbacks.includes(fn)) {
7✔
59
      callbacks.push(fn);
3✔
60
      onCallbackChange(callbacks);
3✔
61
    }
3✔
62
    // 返回取消注册函数
7✔
63
    return () => {
7✔
64
      callbacks = filterItem(callbacks, e => e !== fn);
×
65
      onCallbackChange(callbacks);
×
66
    };
7✔
67
  };
2✔
68

2✔
69
  const triggerCallback = (...args: any[]) => {
2✔
70
    if (callbacks.length > 0) {
2✔
71
      return forEach(callbacks, fn => fn(...args));
2✔
72
    }
2✔
73
  };
2✔
74

2✔
75
  const removeAllCallback = () => {
2✔
76
    callbacks = [];
1✔
77
    onCallbackChange(callbacks);
1✔
78
  };
2✔
79

2✔
80
  return [setCallback, triggerCallback as Fn, removeAllCallback] as const;
2✔
81
}
2✔
82

1✔
83
/**
1✔
84
 * 创建防抖函数,当delay为0时立即触发函数
1✔
85
 * 场景:在调用useWatcher并设置了immediate为true时,首次调用需立即执行,否则会造成延迟调用
1✔
86
 * @param {GeneralFn} fn 回调函数
1✔
87
 * @param {number|(...args: any[]) => number} delay 延迟描述,设置为函数时可实现动态的延迟
1✔
88
 * @returns 延迟后的回调函数
1✔
89
 */
1✔
90
export const debounce = (fn: GeneralFn, delay: number | ((...args: any[]) => number)) => {
1✔
91
  let timer: any = nullValue;
583✔
92
  return function debounceFn(this: any, ...args: any[]) {
583✔
93
    const bindFn = fn.bind(this, ...args);
154✔
94
    const delayMill = isNumber(delay) ? delay : delay(...args);
154!
95
    timer && clearTimeoutTimer(timer);
154✔
96
    if (delayMill > 0) {
154✔
97
      timer = setTimeoutFn(bindFn, delayMill);
13✔
98
    } else {
154✔
99
      bindFn();
141✔
100
    }
141✔
101
  };
583✔
102
};
583✔
103

1✔
104
/**
1✔
105
 * 批量执行事件回调函数,并将args作为参数传入
1✔
106
 * @param handlers 事件回调数组
1✔
107
 * @param args 函数参数
1✔
108
 */
1✔
109
export const runArgsHandler = (handlers: GeneralFn[], ...args: any[]) => {
1✔
110
  let ret: any = undefinedValue;
×
111
  forEach(handlers, handler => {
×
112
    const retInner = handler(...args);
×
113
    ret = retInner !== undefinedValue ? retInner : ret;
×
114
  });
×
115
  return ret;
×
116
};
×
117

1✔
118
/**
1✔
119
 * 获取请求方法对象
1✔
120
 * @param methodHandler 请求方法句柄
1✔
121
 * @param args 方法调用参数
1✔
122
 * @returns 请求方法对象
1✔
123
 */
1✔
124
export const getHandlerMethod = (methodHandler: Method | AlovaMethodHandler, args: any[] = []) => {
1✔
125
  const methodInstance = isFn(methodHandler) ? methodHandler(...args) : methodHandler;
85!
126
  createAssert('scene')(
85✔
127
    instanceOf(methodInstance, Method),
85✔
128
    'hook handler must be a method instance or a function that returns method instance'
85✔
129
  );
85✔
130
  return methodInstance;
85✔
131
};
85✔
132

1✔
133
/**
1✔
134
 * 转换对象的每一项值,并返回新的对象
1✔
135
 * @param obj 对象
1✔
136
 * @param callback 回调函数
1✔
137
 * @returns 转换后的对象
1✔
138
 */
1✔
139
export const mapObject = <T extends Record<string, any>, U>(
1✔
140
  obj: T,
583✔
141
  callback: (value: T[keyof T], key: string, parent: T) => U
583✔
142
) => {
583✔
143
  const ret: Record<string, U> = {};
583✔
144
  for (const key in obj) {
583✔
145
    ret[key] = callback(obj[key], key, obj);
1,128✔
146
  }
1,128✔
147
  return ret as Record<keyof T, U>;
583✔
148
};
583✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc