tools-min-ns 1.12.2 → 1.14.0
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/README.md +7 -0
- package/esm/array/ArrayUtil.d.ts +38 -0
- package/esm/array/ArrayUtil.js +62 -0
- package/esm/request/RequestUtil.d.ts +69 -1
- package/esm/request/RequestUtil.js +74 -7
- package/esm/request/nsPromiseFn.d.ts +74 -0
- package/esm/request/nsPromiseFn.js +128 -0
- package/lib/array/ArrayUtil.d.ts +38 -0
- package/lib/array/ArrayUtil.js +62 -0
- package/lib/request/RequestUtil.d.ts +69 -1
- package/lib/request/RequestUtil.js +74 -7
- package/lib/request/nsPromiseFn.d.ts +74 -0
- package/lib/request/nsPromiseFn.js +133 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,6 +5,13 @@ cnpm i tools-min-ns --save
|
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
# updates
|
|
8
|
+
## v1.14.0
|
|
9
|
+
> ArrayUtil 新增三个分组方法
|
|
10
|
+
## v1.13.0
|
|
11
|
+
> RequestUtil
|
|
12
|
+
- handleRequests 中onUploadProgress新增两个参数nowResponse: T; endResponses: T[]
|
|
13
|
+
- 新增nsPromise 请求处理
|
|
14
|
+
|
|
8
15
|
## v1.12.2
|
|
9
16
|
> DateUtil.formatDate参数为string类型错误
|
|
10
17
|
## v1.12.1
|
package/esm/array/ArrayUtil.d.ts
CHANGED
|
@@ -135,5 +135,43 @@ console.log(universalSort(objArray, obj => obj.name.length)); // [{ name: 'Jim',
|
|
|
135
135
|
console.log(universalSort([5, 3, 8, 1, 2], null, 'desc')); // [8, 5, 3, 2, 1]
|
|
136
136
|
*/
|
|
137
137
|
function universalSort<T>(array: T[], key?: keyof T | ((item: T) => any), order?: 'asc' | 'desc'): T[];
|
|
138
|
+
/**
|
|
139
|
+
* 根据对象的属性值进行分组
|
|
140
|
+
* @param array 对象数组
|
|
141
|
+
* @param key 对象的key
|
|
142
|
+
* @example
|
|
143
|
+
const data = [
|
|
144
|
+
{ name: 'Alice', age: 21 },
|
|
145
|
+
{ name: 'Bob', age: 25 },
|
|
146
|
+
{ name: 'Charlie', age: 21 },
|
|
147
|
+
{ name: 'David', age: 25 }
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
const groupedByAge = groupBy(data, 'age');
|
|
151
|
+
console.log(groupedByAge); // {21: Array(2), 25: Array(2)}
|
|
152
|
+
*/
|
|
153
|
+
function groupBy<T>(array: T[], key: keyof T): Record<keyof T, T[]>;
|
|
154
|
+
/**
|
|
155
|
+
* 按条件分组
|
|
156
|
+
* @param array 对象数组
|
|
157
|
+
* @param condition filter
|
|
158
|
+
* @example
|
|
159
|
+
const numbers: number[] = [1, 2, 3, 4, 5, 6];
|
|
160
|
+
|
|
161
|
+
const groupedByOddEven = groupByCondition(numbers, num => num % 2 === 0);
|
|
162
|
+
console.log(groupedByOddEven); // {false: Array(3), true: Array(3)}
|
|
163
|
+
*/
|
|
164
|
+
function groupByCondition<T>(array: T[], condition: (value: T) => boolean): Record<'true' | 'false', T[]>;
|
|
165
|
+
/**
|
|
166
|
+
* 按固定大小分组
|
|
167
|
+
* @param array 对象数组
|
|
168
|
+
* @param size 数量
|
|
169
|
+
* @example
|
|
170
|
+
const data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
171
|
+
|
|
172
|
+
const chunkedArray = chunkArray(data, 3);
|
|
173
|
+
console.log(chunkedArray);// [Array(3), Array(3), Array(3)]
|
|
174
|
+
*/
|
|
175
|
+
function chunkArray<T>(array: T[], size: number): T[][];
|
|
138
176
|
}
|
|
139
177
|
export default ArrayUtil;
|
package/esm/array/ArrayUtil.js
CHANGED
|
@@ -309,5 +309,67 @@ var ArrayUtil;
|
|
|
309
309
|
return array.sort(compareFunction);
|
|
310
310
|
}
|
|
311
311
|
ArrayUtil.universalSort = universalSort;
|
|
312
|
+
/**
|
|
313
|
+
* 根据对象的属性值进行分组
|
|
314
|
+
* @param array 对象数组
|
|
315
|
+
* @param key 对象的key
|
|
316
|
+
* @example
|
|
317
|
+
const data = [
|
|
318
|
+
{ name: 'Alice', age: 21 },
|
|
319
|
+
{ name: 'Bob', age: 25 },
|
|
320
|
+
{ name: 'Charlie', age: 21 },
|
|
321
|
+
{ name: 'David', age: 25 }
|
|
322
|
+
];
|
|
323
|
+
const groupedByAge = groupBy(data, 'age');
|
|
324
|
+
console.log(groupedByAge); // {21: Array(2), 25: Array(2)}
|
|
325
|
+
*/
|
|
326
|
+
function groupBy(array, key) {
|
|
327
|
+
return array.reduce(function (result, currentValue) {
|
|
328
|
+
var groupKey = currentValue[key];
|
|
329
|
+
if (!result[groupKey]) {
|
|
330
|
+
result[groupKey] = [];
|
|
331
|
+
}
|
|
332
|
+
result[groupKey].push(currentValue);
|
|
333
|
+
return result;
|
|
334
|
+
}, {});
|
|
335
|
+
}
|
|
336
|
+
ArrayUtil.groupBy = groupBy;
|
|
337
|
+
/**
|
|
338
|
+
* 按条件分组
|
|
339
|
+
* @param array 对象数组
|
|
340
|
+
* @param condition filter
|
|
341
|
+
* @example
|
|
342
|
+
const numbers: number[] = [1, 2, 3, 4, 5, 6];
|
|
343
|
+
const groupedByOddEven = groupByCondition(numbers, num => num % 2 === 0);
|
|
344
|
+
console.log(groupedByOddEven); // {false: Array(3), true: Array(3)}
|
|
345
|
+
*/
|
|
346
|
+
function groupByCondition(array, condition) {
|
|
347
|
+
return array.reduce(function (result, currentValue) {
|
|
348
|
+
var groupKey = condition(currentValue) ? 'true' : 'false';
|
|
349
|
+
if (!result[groupKey]) {
|
|
350
|
+
result[groupKey] = [];
|
|
351
|
+
}
|
|
352
|
+
result[groupKey].push(currentValue);
|
|
353
|
+
return result;
|
|
354
|
+
}, {});
|
|
355
|
+
}
|
|
356
|
+
ArrayUtil.groupByCondition = groupByCondition;
|
|
357
|
+
/**
|
|
358
|
+
* 按固定大小分组
|
|
359
|
+
* @param array 对象数组
|
|
360
|
+
* @param size 数量
|
|
361
|
+
* @example
|
|
362
|
+
const data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
363
|
+
const chunkedArray = chunkArray(data, 3);
|
|
364
|
+
console.log(chunkedArray);// [Array(3), Array(3), Array(3)]
|
|
365
|
+
*/
|
|
366
|
+
function chunkArray(array, size) {
|
|
367
|
+
var result = [];
|
|
368
|
+
for (var i = 0; i < array.length; i += size) {
|
|
369
|
+
result.push(array.slice(i, i + size));
|
|
370
|
+
}
|
|
371
|
+
return result;
|
|
372
|
+
}
|
|
373
|
+
ArrayUtil.chunkArray = chunkArray;
|
|
312
374
|
})(ArrayUtil || (ArrayUtil = {}));
|
|
313
375
|
export default ArrayUtil;
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import mgop, { setDefaultHeader } from './mgop';
|
|
8
8
|
import uniRquestFn from './uniRquest';
|
|
9
9
|
import jsonpFn, { jsonpRquest as jsonpRquestFn } from './jsonp';
|
|
10
|
+
import nsPromiseFn from './nsPromiseFn';
|
|
11
|
+
export type PromiseInput<T> = Array<(() => Promise<T>) | Promise<T>> | (() => Promise<T>) | Promise<T>;
|
|
10
12
|
declare namespace RequestUtil {
|
|
11
13
|
/** @name 浙里办请求工具设置默认请求头 */
|
|
12
14
|
const mgopSetDefaultHeader: typeof setDefaultHeader;
|
|
@@ -54,13 +56,79 @@ declare namespace RequestUtil {
|
|
|
54
56
|
* @param options limit同时处理几个请求默认6个,onUploadProgress进度条
|
|
55
57
|
* @returns
|
|
56
58
|
*/
|
|
57
|
-
function handleRequests<T = any>(requests:
|
|
59
|
+
function handleRequests<T = any>(requests: PromiseInput<T>, options?: {
|
|
58
60
|
limit?: number;
|
|
59
61
|
onUploadProgress?: (opt: {
|
|
60
62
|
total: number;
|
|
61
63
|
loaded: number;
|
|
62
64
|
progress: number;
|
|
65
|
+
nowResponse: T;
|
|
66
|
+
endResponses: T[];
|
|
63
67
|
}) => void;
|
|
64
68
|
}): Promise<T[]>;
|
|
69
|
+
/**
|
|
70
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
71
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
72
|
+
* @param {Object} options - 配置选项
|
|
73
|
+
* @param {number} options.limit - 并发限制默认10
|
|
74
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
75
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
76
|
+
* @example
|
|
77
|
+
*
|
|
78
|
+
// 示例方法:返回 Promise 的函数
|
|
79
|
+
function exampleAsyncFunction() {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
const isSuccess = Math.random() > 0.5;
|
|
83
|
+
if (isSuccess) {
|
|
84
|
+
resolve('Success data');
|
|
85
|
+
} else {
|
|
86
|
+
reject(new Error('Something went wrong'));
|
|
87
|
+
}
|
|
88
|
+
}, 1000);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 使用封装的 nsPromise 方法
|
|
93
|
+
(async () => {
|
|
94
|
+
const [err, result, isStopped] = await nsPromise(
|
|
95
|
+
exampleAsyncFunction,
|
|
96
|
+
{
|
|
97
|
+
limit: 10, // 控制并发数量
|
|
98
|
+
stop: (stopExecution) => {
|
|
99
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
console.log('Error:', err);//Error: null
|
|
105
|
+
console.log('Result:', result);//Result: null
|
|
106
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
107
|
+
|
|
108
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
109
|
+
[
|
|
110
|
+
exampleAsyncFunction,
|
|
111
|
+
exampleAsyncFunction,
|
|
112
|
+
exampleAsyncFunction,
|
|
113
|
+
exampleAsyncFunction,
|
|
114
|
+
exampleAsyncFunction,
|
|
115
|
+
exampleAsyncFunction,
|
|
116
|
+
exampleAsyncFunction,
|
|
117
|
+
exampleAsyncFunction,
|
|
118
|
+
],
|
|
119
|
+
{
|
|
120
|
+
limit: 10, // 控制并发数量
|
|
121
|
+
stop: (stopExecution) => {
|
|
122
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
128
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
129
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
130
|
+
})();
|
|
131
|
+
*/
|
|
132
|
+
const nsPromise: typeof nsPromiseFn;
|
|
65
133
|
}
|
|
66
134
|
export default RequestUtil;
|
|
@@ -122,6 +122,7 @@ var __generator = this && this.__generator || function (thisArg, body) {
|
|
|
122
122
|
import mgop, { setDefaultHeader } from './mgop';
|
|
123
123
|
import uniRquestFn from './uniRquest';
|
|
124
124
|
import jsonpFn, { jsonpRquest as jsonpRquestFn } from './jsonp';
|
|
125
|
+
import nsPromiseFn from './nsPromiseFn';
|
|
125
126
|
var RequestUtil;
|
|
126
127
|
(function (RequestUtil) {
|
|
127
128
|
/** @name 浙里办请求工具设置默认请求头 */
|
|
@@ -180,8 +181,8 @@ var RequestUtil;
|
|
|
180
181
|
return __generator(this, function (_a) {
|
|
181
182
|
switch (_a.label) {
|
|
182
183
|
case 0:
|
|
183
|
-
if (!
|
|
184
|
-
res =
|
|
184
|
+
if (!functionArray.length) return [2 /*return*/];
|
|
185
|
+
res = functionArray.shift();
|
|
185
186
|
if (!res) return [2 /*return*/];
|
|
186
187
|
return [4 /*yield*/, res()];
|
|
187
188
|
case 1:
|
|
@@ -199,21 +200,27 @@ var RequestUtil;
|
|
|
199
200
|
onUploadProgress === null || onUploadProgress === void 0 ? void 0 : onUploadProgress({
|
|
200
201
|
total: resLength,
|
|
201
202
|
loaded: loaded,
|
|
202
|
-
progress: loaded / resLength
|
|
203
|
+
progress: loaded / resLength,
|
|
204
|
+
nowResponse: result,
|
|
205
|
+
endResponses: results
|
|
203
206
|
});
|
|
204
|
-
_a.label = 3;
|
|
205
|
-
case 3:
|
|
206
207
|
return [2 /*return*/];
|
|
207
208
|
}
|
|
208
209
|
});
|
|
209
210
|
});
|
|
210
211
|
}
|
|
211
|
-
var _a, _b, limit, onUploadProgress, resLength, results, loaded, concurrent;
|
|
212
|
+
var _a, _b, limit, onUploadProgress, requestArray, functionArray, resLength, results, loaded, concurrent;
|
|
212
213
|
return __generator(this, function (_c) {
|
|
213
214
|
switch (_c.label) {
|
|
214
215
|
case 0:
|
|
215
216
|
_a = options !== null && options !== void 0 ? options : {}, _b = _a.limit, limit = _b === void 0 ? 6 : _b, onUploadProgress = _a.onUploadProgress;
|
|
216
|
-
|
|
217
|
+
requestArray = Array.isArray(requests) ? requests : [requests];
|
|
218
|
+
functionArray = requestArray.map(function (request) {
|
|
219
|
+
return typeof request === 'function' ? request : function () {
|
|
220
|
+
return Promise.resolve(request);
|
|
221
|
+
};
|
|
222
|
+
});
|
|
223
|
+
resLength = functionArray.length;
|
|
217
224
|
results = [];
|
|
218
225
|
loaded = 0;
|
|
219
226
|
concurrent = Array.from({
|
|
@@ -233,5 +240,65 @@ var RequestUtil;
|
|
|
233
240
|
});
|
|
234
241
|
}
|
|
235
242
|
RequestUtil.handleRequests = handleRequests;
|
|
243
|
+
/**
|
|
244
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
245
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
246
|
+
* @param {Object} options - 配置选项
|
|
247
|
+
* @param {number} options.limit - 并发限制默认10
|
|
248
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
249
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
250
|
+
* @example
|
|
251
|
+
*
|
|
252
|
+
// 示例方法:返回 Promise 的函数
|
|
253
|
+
function exampleAsyncFunction() {
|
|
254
|
+
return new Promise((resolve, reject) => {
|
|
255
|
+
setTimeout(() => {
|
|
256
|
+
const isSuccess = Math.random() > 0.5;
|
|
257
|
+
if (isSuccess) {
|
|
258
|
+
resolve('Success data');
|
|
259
|
+
} else {
|
|
260
|
+
reject(new Error('Something went wrong'));
|
|
261
|
+
}
|
|
262
|
+
}, 1000);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// 使用封装的 nsPromise 方法
|
|
266
|
+
(async () => {
|
|
267
|
+
const [err, result, isStopped] = await nsPromise(
|
|
268
|
+
exampleAsyncFunction,
|
|
269
|
+
{
|
|
270
|
+
limit: 10, // 控制并发数量
|
|
271
|
+
stop: (stopExecution) => {
|
|
272
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
);
|
|
276
|
+
console.log('Error:', err);//Error: null
|
|
277
|
+
console.log('Result:', result);//Result: null
|
|
278
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
279
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
280
|
+
[
|
|
281
|
+
exampleAsyncFunction,
|
|
282
|
+
exampleAsyncFunction,
|
|
283
|
+
exampleAsyncFunction,
|
|
284
|
+
exampleAsyncFunction,
|
|
285
|
+
exampleAsyncFunction,
|
|
286
|
+
exampleAsyncFunction,
|
|
287
|
+
exampleAsyncFunction,
|
|
288
|
+
exampleAsyncFunction,
|
|
289
|
+
],
|
|
290
|
+
{
|
|
291
|
+
limit: 10, // 控制并发数量
|
|
292
|
+
stop: (stopExecution) => {
|
|
293
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
);
|
|
297
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
298
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
299
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
300
|
+
})();
|
|
301
|
+
*/
|
|
302
|
+
RequestUtil.nsPromise = nsPromiseFn;
|
|
236
303
|
})(RequestUtil || (RequestUtil = {}));
|
|
237
304
|
export default RequestUtil;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { PromiseInput } from './RequestUtil';
|
|
2
|
+
interface Options {
|
|
3
|
+
/** @default 10 */
|
|
4
|
+
limit?: number;
|
|
5
|
+
stop?: (stopFn: () => void) => void;
|
|
6
|
+
}
|
|
7
|
+
type SingleResultTuple<T> = [Error | null, T | null, boolean];
|
|
8
|
+
type MultipleResultTuple<T> = [(Error | null)[], (T | null)[], boolean];
|
|
9
|
+
type Result<T, I> = I extends Array<any> ? MultipleResultTuple<T> : SingleResultTuple<T>;
|
|
10
|
+
/**
|
|
11
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
12
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
13
|
+
* @param {Object} options - 配置选项
|
|
14
|
+
* @param {number} options.limit - 并发限制默认10
|
|
15
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
16
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
17
|
+
* @example
|
|
18
|
+
*
|
|
19
|
+
// 示例方法:返回 Promise 的函数
|
|
20
|
+
function exampleAsyncFunction() {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
setTimeout(() => {
|
|
23
|
+
const isSuccess = Math.random() > 0.5;
|
|
24
|
+
if (isSuccess) {
|
|
25
|
+
resolve('Success data');
|
|
26
|
+
} else {
|
|
27
|
+
reject(new Error('Something went wrong'));
|
|
28
|
+
}
|
|
29
|
+
}, 1000);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 使用封装的 nsPromise 方法
|
|
34
|
+
(async () => {
|
|
35
|
+
const [err, result, isStopped] = await nsPromise(
|
|
36
|
+
exampleAsyncFunction,
|
|
37
|
+
{
|
|
38
|
+
limit: 10, // 控制并发数量
|
|
39
|
+
stop: (stopExecution) => {
|
|
40
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
console.log('Error:', err);//Error: null
|
|
46
|
+
console.log('Result:', result);//Result: null
|
|
47
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
48
|
+
|
|
49
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
50
|
+
[
|
|
51
|
+
exampleAsyncFunction,
|
|
52
|
+
exampleAsyncFunction,
|
|
53
|
+
exampleAsyncFunction,
|
|
54
|
+
exampleAsyncFunction,
|
|
55
|
+
exampleAsyncFunction,
|
|
56
|
+
exampleAsyncFunction,
|
|
57
|
+
exampleAsyncFunction,
|
|
58
|
+
exampleAsyncFunction,
|
|
59
|
+
],
|
|
60
|
+
{
|
|
61
|
+
limit: 10, // 控制并发数量
|
|
62
|
+
stop: (stopExecution) => {
|
|
63
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
69
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
70
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
71
|
+
})();
|
|
72
|
+
*/
|
|
73
|
+
declare function nsPromiseFn<T = any, I = PromiseInput<T>>(input: I, options?: Options): Promise<Result<T, I>>;
|
|
74
|
+
export default nsPromiseFn;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
3
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
4
|
+
* @param {Object} options - 配置选项
|
|
5
|
+
* @param {number} options.limit - 并发限制默认10
|
|
6
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
7
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
8
|
+
* @example
|
|
9
|
+
*
|
|
10
|
+
// 示例方法:返回 Promise 的函数
|
|
11
|
+
function exampleAsyncFunction() {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
setTimeout(() => {
|
|
14
|
+
const isSuccess = Math.random() > 0.5;
|
|
15
|
+
if (isSuccess) {
|
|
16
|
+
resolve('Success data');
|
|
17
|
+
} else {
|
|
18
|
+
reject(new Error('Something went wrong'));
|
|
19
|
+
}
|
|
20
|
+
}, 1000);
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 使用封装的 nsPromise 方法
|
|
25
|
+
(async () => {
|
|
26
|
+
const [err, result, isStopped] = await nsPromise(
|
|
27
|
+
exampleAsyncFunction,
|
|
28
|
+
{
|
|
29
|
+
limit: 10, // 控制并发数量
|
|
30
|
+
stop: (stopExecution) => {
|
|
31
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
console.log('Error:', err);//Error: null
|
|
37
|
+
console.log('Result:', result);//Result: null
|
|
38
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
39
|
+
|
|
40
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
41
|
+
[
|
|
42
|
+
exampleAsyncFunction,
|
|
43
|
+
exampleAsyncFunction,
|
|
44
|
+
exampleAsyncFunction,
|
|
45
|
+
exampleAsyncFunction,
|
|
46
|
+
exampleAsyncFunction,
|
|
47
|
+
exampleAsyncFunction,
|
|
48
|
+
exampleAsyncFunction,
|
|
49
|
+
exampleAsyncFunction,
|
|
50
|
+
],
|
|
51
|
+
{
|
|
52
|
+
limit: 10, // 控制并发数量
|
|
53
|
+
stop: (stopExecution) => {
|
|
54
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
60
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
61
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
62
|
+
})();
|
|
63
|
+
*/
|
|
64
|
+
function nsPromiseFn(input, options) {
|
|
65
|
+
if (options === void 0) {
|
|
66
|
+
options = {};
|
|
67
|
+
}
|
|
68
|
+
var _a = options.limit,
|
|
69
|
+
limit = _a === void 0 ? 10 : _a,
|
|
70
|
+
stop = options.stop;
|
|
71
|
+
var isStopped = false;
|
|
72
|
+
var activePromises = 0;
|
|
73
|
+
var currentIndex = 0;
|
|
74
|
+
var results = [];
|
|
75
|
+
var errors = [];
|
|
76
|
+
var isArrayInput = Array.isArray(input);
|
|
77
|
+
var promiseFunctions = isArrayInput ? input : [input];
|
|
78
|
+
var stopPromise = new Promise(function (_, reject) {
|
|
79
|
+
stop === null || stop === void 0 ? void 0 : stop(function () {
|
|
80
|
+
isStopped = true;
|
|
81
|
+
reject(new Error('Stopped'));
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
return new Promise(function (resolve) {
|
|
85
|
+
var executeNext = function executeNext() {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
if (currentIndex >= promiseFunctions.length && activePromises === 0) {
|
|
88
|
+
if (isArrayInput) {
|
|
89
|
+
resolve([errors, results, isStopped]);
|
|
90
|
+
} else {
|
|
91
|
+
resolve([(_a = errors[0]) !== null && _a !== void 0 ? _a : null, (_b = results[0]) !== null && _b !== void 0 ? _b : null, isStopped]);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
while (activePromises < limit && currentIndex < promiseFunctions.length) {
|
|
96
|
+
var current = promiseFunctions[currentIndex];
|
|
97
|
+
currentIndex += 1;
|
|
98
|
+
activePromises += 1;
|
|
99
|
+
var promise = typeof current === 'function' ? current() : current;
|
|
100
|
+
Promise.race([promise, stopPromise]).then(function (data) {
|
|
101
|
+
if (!isStopped) {
|
|
102
|
+
results.push(data);
|
|
103
|
+
errors.push(null);
|
|
104
|
+
}
|
|
105
|
+
}).catch(function (err) {
|
|
106
|
+
if (!isStopped || err.message === 'Stopped') {
|
|
107
|
+
results.push(null);
|
|
108
|
+
errors.push(err);
|
|
109
|
+
}
|
|
110
|
+
}).finally(function () {
|
|
111
|
+
var _a, _b;
|
|
112
|
+
activePromises -= 1;
|
|
113
|
+
if (!isStopped) {
|
|
114
|
+
executeNext();
|
|
115
|
+
} else if (activePromises === 0) {
|
|
116
|
+
if (isArrayInput) {
|
|
117
|
+
resolve([errors, results, isStopped]);
|
|
118
|
+
} else {
|
|
119
|
+
resolve([(_a = errors[0]) !== null && _a !== void 0 ? _a : null, (_b = results[0]) !== null && _b !== void 0 ? _b : null, isStopped]);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
executeNext();
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
export default nsPromiseFn;
|
package/lib/array/ArrayUtil.d.ts
CHANGED
|
@@ -135,5 +135,43 @@ console.log(universalSort(objArray, obj => obj.name.length)); // [{ name: 'Jim',
|
|
|
135
135
|
console.log(universalSort([5, 3, 8, 1, 2], null, 'desc')); // [8, 5, 3, 2, 1]
|
|
136
136
|
*/
|
|
137
137
|
function universalSort<T>(array: T[], key?: keyof T | ((item: T) => any), order?: 'asc' | 'desc'): T[];
|
|
138
|
+
/**
|
|
139
|
+
* 根据对象的属性值进行分组
|
|
140
|
+
* @param array 对象数组
|
|
141
|
+
* @param key 对象的key
|
|
142
|
+
* @example
|
|
143
|
+
const data = [
|
|
144
|
+
{ name: 'Alice', age: 21 },
|
|
145
|
+
{ name: 'Bob', age: 25 },
|
|
146
|
+
{ name: 'Charlie', age: 21 },
|
|
147
|
+
{ name: 'David', age: 25 }
|
|
148
|
+
];
|
|
149
|
+
|
|
150
|
+
const groupedByAge = groupBy(data, 'age');
|
|
151
|
+
console.log(groupedByAge); // {21: Array(2), 25: Array(2)}
|
|
152
|
+
*/
|
|
153
|
+
function groupBy<T>(array: T[], key: keyof T): Record<keyof T, T[]>;
|
|
154
|
+
/**
|
|
155
|
+
* 按条件分组
|
|
156
|
+
* @param array 对象数组
|
|
157
|
+
* @param condition filter
|
|
158
|
+
* @example
|
|
159
|
+
const numbers: number[] = [1, 2, 3, 4, 5, 6];
|
|
160
|
+
|
|
161
|
+
const groupedByOddEven = groupByCondition(numbers, num => num % 2 === 0);
|
|
162
|
+
console.log(groupedByOddEven); // {false: Array(3), true: Array(3)}
|
|
163
|
+
*/
|
|
164
|
+
function groupByCondition<T>(array: T[], condition: (value: T) => boolean): Record<'true' | 'false', T[]>;
|
|
165
|
+
/**
|
|
166
|
+
* 按固定大小分组
|
|
167
|
+
* @param array 对象数组
|
|
168
|
+
* @param size 数量
|
|
169
|
+
* @example
|
|
170
|
+
const data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
171
|
+
|
|
172
|
+
const chunkedArray = chunkArray(data, 3);
|
|
173
|
+
console.log(chunkedArray);// [Array(3), Array(3), Array(3)]
|
|
174
|
+
*/
|
|
175
|
+
function chunkArray<T>(array: T[], size: number): T[][];
|
|
138
176
|
}
|
|
139
177
|
export default ArrayUtil;
|
package/lib/array/ArrayUtil.js
CHANGED
|
@@ -319,5 +319,67 @@ var ArrayUtil;
|
|
|
319
319
|
return array.sort(compareFunction);
|
|
320
320
|
}
|
|
321
321
|
ArrayUtil.universalSort = universalSort;
|
|
322
|
+
/**
|
|
323
|
+
* 根据对象的属性值进行分组
|
|
324
|
+
* @param array 对象数组
|
|
325
|
+
* @param key 对象的key
|
|
326
|
+
* @example
|
|
327
|
+
const data = [
|
|
328
|
+
{ name: 'Alice', age: 21 },
|
|
329
|
+
{ name: 'Bob', age: 25 },
|
|
330
|
+
{ name: 'Charlie', age: 21 },
|
|
331
|
+
{ name: 'David', age: 25 }
|
|
332
|
+
];
|
|
333
|
+
const groupedByAge = groupBy(data, 'age');
|
|
334
|
+
console.log(groupedByAge); // {21: Array(2), 25: Array(2)}
|
|
335
|
+
*/
|
|
336
|
+
function groupBy(array, key) {
|
|
337
|
+
return array.reduce(function (result, currentValue) {
|
|
338
|
+
var groupKey = currentValue[key];
|
|
339
|
+
if (!result[groupKey]) {
|
|
340
|
+
result[groupKey] = [];
|
|
341
|
+
}
|
|
342
|
+
result[groupKey].push(currentValue);
|
|
343
|
+
return result;
|
|
344
|
+
}, {});
|
|
345
|
+
}
|
|
346
|
+
ArrayUtil.groupBy = groupBy;
|
|
347
|
+
/**
|
|
348
|
+
* 按条件分组
|
|
349
|
+
* @param array 对象数组
|
|
350
|
+
* @param condition filter
|
|
351
|
+
* @example
|
|
352
|
+
const numbers: number[] = [1, 2, 3, 4, 5, 6];
|
|
353
|
+
const groupedByOddEven = groupByCondition(numbers, num => num % 2 === 0);
|
|
354
|
+
console.log(groupedByOddEven); // {false: Array(3), true: Array(3)}
|
|
355
|
+
*/
|
|
356
|
+
function groupByCondition(array, condition) {
|
|
357
|
+
return array.reduce(function (result, currentValue) {
|
|
358
|
+
var groupKey = condition(currentValue) ? 'true' : 'false';
|
|
359
|
+
if (!result[groupKey]) {
|
|
360
|
+
result[groupKey] = [];
|
|
361
|
+
}
|
|
362
|
+
result[groupKey].push(currentValue);
|
|
363
|
+
return result;
|
|
364
|
+
}, {});
|
|
365
|
+
}
|
|
366
|
+
ArrayUtil.groupByCondition = groupByCondition;
|
|
367
|
+
/**
|
|
368
|
+
* 按固定大小分组
|
|
369
|
+
* @param array 对象数组
|
|
370
|
+
* @param size 数量
|
|
371
|
+
* @example
|
|
372
|
+
const data: number[] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
|
373
|
+
const chunkedArray = chunkArray(data, 3);
|
|
374
|
+
console.log(chunkedArray);// [Array(3), Array(3), Array(3)]
|
|
375
|
+
*/
|
|
376
|
+
function chunkArray(array, size) {
|
|
377
|
+
var result = [];
|
|
378
|
+
for (var i = 0; i < array.length; i += size) {
|
|
379
|
+
result.push(array.slice(i, i + size));
|
|
380
|
+
}
|
|
381
|
+
return result;
|
|
382
|
+
}
|
|
383
|
+
ArrayUtil.chunkArray = chunkArray;
|
|
322
384
|
})(ArrayUtil || (ArrayUtil = {}));
|
|
323
385
|
exports.default = ArrayUtil;
|
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
import mgop, { setDefaultHeader } from './mgop';
|
|
8
8
|
import uniRquestFn from './uniRquest';
|
|
9
9
|
import jsonpFn, { jsonpRquest as jsonpRquestFn } from './jsonp';
|
|
10
|
+
import nsPromiseFn from './nsPromiseFn';
|
|
11
|
+
export type PromiseInput<T> = Array<(() => Promise<T>) | Promise<T>> | (() => Promise<T>) | Promise<T>;
|
|
10
12
|
declare namespace RequestUtil {
|
|
11
13
|
/** @name 浙里办请求工具设置默认请求头 */
|
|
12
14
|
const mgopSetDefaultHeader: typeof setDefaultHeader;
|
|
@@ -54,13 +56,79 @@ declare namespace RequestUtil {
|
|
|
54
56
|
* @param options limit同时处理几个请求默认6个,onUploadProgress进度条
|
|
55
57
|
* @returns
|
|
56
58
|
*/
|
|
57
|
-
function handleRequests<T = any>(requests:
|
|
59
|
+
function handleRequests<T = any>(requests: PromiseInput<T>, options?: {
|
|
58
60
|
limit?: number;
|
|
59
61
|
onUploadProgress?: (opt: {
|
|
60
62
|
total: number;
|
|
61
63
|
loaded: number;
|
|
62
64
|
progress: number;
|
|
65
|
+
nowResponse: T;
|
|
66
|
+
endResponses: T[];
|
|
63
67
|
}) => void;
|
|
64
68
|
}): Promise<T[]>;
|
|
69
|
+
/**
|
|
70
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
71
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
72
|
+
* @param {Object} options - 配置选项
|
|
73
|
+
* @param {number} options.limit - 并发限制默认10
|
|
74
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
75
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
76
|
+
* @example
|
|
77
|
+
*
|
|
78
|
+
// 示例方法:返回 Promise 的函数
|
|
79
|
+
function exampleAsyncFunction() {
|
|
80
|
+
return new Promise((resolve, reject) => {
|
|
81
|
+
setTimeout(() => {
|
|
82
|
+
const isSuccess = Math.random() > 0.5;
|
|
83
|
+
if (isSuccess) {
|
|
84
|
+
resolve('Success data');
|
|
85
|
+
} else {
|
|
86
|
+
reject(new Error('Something went wrong'));
|
|
87
|
+
}
|
|
88
|
+
}, 1000);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// 使用封装的 nsPromise 方法
|
|
93
|
+
(async () => {
|
|
94
|
+
const [err, result, isStopped] = await nsPromise(
|
|
95
|
+
exampleAsyncFunction,
|
|
96
|
+
{
|
|
97
|
+
limit: 10, // 控制并发数量
|
|
98
|
+
stop: (stopExecution) => {
|
|
99
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
console.log('Error:', err);//Error: null
|
|
105
|
+
console.log('Result:', result);//Result: null
|
|
106
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
107
|
+
|
|
108
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
109
|
+
[
|
|
110
|
+
exampleAsyncFunction,
|
|
111
|
+
exampleAsyncFunction,
|
|
112
|
+
exampleAsyncFunction,
|
|
113
|
+
exampleAsyncFunction,
|
|
114
|
+
exampleAsyncFunction,
|
|
115
|
+
exampleAsyncFunction,
|
|
116
|
+
exampleAsyncFunction,
|
|
117
|
+
exampleAsyncFunction,
|
|
118
|
+
],
|
|
119
|
+
{
|
|
120
|
+
limit: 10, // 控制并发数量
|
|
121
|
+
stop: (stopExecution) => {
|
|
122
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
128
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
129
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
130
|
+
})();
|
|
131
|
+
*/
|
|
132
|
+
const nsPromise: typeof nsPromiseFn;
|
|
65
133
|
}
|
|
66
134
|
export default RequestUtil;
|
|
@@ -163,6 +163,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
163
163
|
var mgop_1 = __importStar(require("./mgop"));
|
|
164
164
|
var uniRquest_1 = __importDefault(require("./uniRquest"));
|
|
165
165
|
var jsonp_1 = __importStar(require("./jsonp"));
|
|
166
|
+
var nsPromiseFn_1 = __importDefault(require("./nsPromiseFn"));
|
|
166
167
|
var RequestUtil;
|
|
167
168
|
(function (RequestUtil) {
|
|
168
169
|
/** @name 浙里办请求工具设置默认请求头 */
|
|
@@ -221,8 +222,8 @@ var RequestUtil;
|
|
|
221
222
|
return __generator(this, function (_a) {
|
|
222
223
|
switch (_a.label) {
|
|
223
224
|
case 0:
|
|
224
|
-
if (!
|
|
225
|
-
res =
|
|
225
|
+
if (!functionArray.length) return [2 /*return*/];
|
|
226
|
+
res = functionArray.shift();
|
|
226
227
|
if (!res) return [2 /*return*/];
|
|
227
228
|
return [4 /*yield*/, res()];
|
|
228
229
|
case 1:
|
|
@@ -240,21 +241,27 @@ var RequestUtil;
|
|
|
240
241
|
onUploadProgress === null || onUploadProgress === void 0 ? void 0 : onUploadProgress({
|
|
241
242
|
total: resLength,
|
|
242
243
|
loaded: loaded,
|
|
243
|
-
progress: loaded / resLength
|
|
244
|
+
progress: loaded / resLength,
|
|
245
|
+
nowResponse: result,
|
|
246
|
+
endResponses: results
|
|
244
247
|
});
|
|
245
|
-
_a.label = 3;
|
|
246
|
-
case 3:
|
|
247
248
|
return [2 /*return*/];
|
|
248
249
|
}
|
|
249
250
|
});
|
|
250
251
|
});
|
|
251
252
|
}
|
|
252
|
-
var _a, _b, limit, onUploadProgress, resLength, results, loaded, concurrent;
|
|
253
|
+
var _a, _b, limit, onUploadProgress, requestArray, functionArray, resLength, results, loaded, concurrent;
|
|
253
254
|
return __generator(this, function (_c) {
|
|
254
255
|
switch (_c.label) {
|
|
255
256
|
case 0:
|
|
256
257
|
_a = options !== null && options !== void 0 ? options : {}, _b = _a.limit, limit = _b === void 0 ? 6 : _b, onUploadProgress = _a.onUploadProgress;
|
|
257
|
-
|
|
258
|
+
requestArray = Array.isArray(requests) ? requests : [requests];
|
|
259
|
+
functionArray = requestArray.map(function (request) {
|
|
260
|
+
return typeof request === 'function' ? request : function () {
|
|
261
|
+
return Promise.resolve(request);
|
|
262
|
+
};
|
|
263
|
+
});
|
|
264
|
+
resLength = functionArray.length;
|
|
258
265
|
results = [];
|
|
259
266
|
loaded = 0;
|
|
260
267
|
concurrent = Array.from({
|
|
@@ -274,5 +281,65 @@ var RequestUtil;
|
|
|
274
281
|
});
|
|
275
282
|
}
|
|
276
283
|
RequestUtil.handleRequests = handleRequests;
|
|
284
|
+
/**
|
|
285
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
286
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
287
|
+
* @param {Object} options - 配置选项
|
|
288
|
+
* @param {number} options.limit - 并发限制默认10
|
|
289
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
290
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
291
|
+
* @example
|
|
292
|
+
*
|
|
293
|
+
// 示例方法:返回 Promise 的函数
|
|
294
|
+
function exampleAsyncFunction() {
|
|
295
|
+
return new Promise((resolve, reject) => {
|
|
296
|
+
setTimeout(() => {
|
|
297
|
+
const isSuccess = Math.random() > 0.5;
|
|
298
|
+
if (isSuccess) {
|
|
299
|
+
resolve('Success data');
|
|
300
|
+
} else {
|
|
301
|
+
reject(new Error('Something went wrong'));
|
|
302
|
+
}
|
|
303
|
+
}, 1000);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
// 使用封装的 nsPromise 方法
|
|
307
|
+
(async () => {
|
|
308
|
+
const [err, result, isStopped] = await nsPromise(
|
|
309
|
+
exampleAsyncFunction,
|
|
310
|
+
{
|
|
311
|
+
limit: 10, // 控制并发数量
|
|
312
|
+
stop: (stopExecution) => {
|
|
313
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
);
|
|
317
|
+
console.log('Error:', err);//Error: null
|
|
318
|
+
console.log('Result:', result);//Result: null
|
|
319
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
320
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
321
|
+
[
|
|
322
|
+
exampleAsyncFunction,
|
|
323
|
+
exampleAsyncFunction,
|
|
324
|
+
exampleAsyncFunction,
|
|
325
|
+
exampleAsyncFunction,
|
|
326
|
+
exampleAsyncFunction,
|
|
327
|
+
exampleAsyncFunction,
|
|
328
|
+
exampleAsyncFunction,
|
|
329
|
+
exampleAsyncFunction,
|
|
330
|
+
],
|
|
331
|
+
{
|
|
332
|
+
limit: 10, // 控制并发数量
|
|
333
|
+
stop: (stopExecution) => {
|
|
334
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
);
|
|
338
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
339
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
340
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
341
|
+
})();
|
|
342
|
+
*/
|
|
343
|
+
RequestUtil.nsPromise = nsPromiseFn_1.default;
|
|
277
344
|
})(RequestUtil || (RequestUtil = {}));
|
|
278
345
|
exports.default = RequestUtil;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { PromiseInput } from './RequestUtil';
|
|
2
|
+
interface Options {
|
|
3
|
+
/** @default 10 */
|
|
4
|
+
limit?: number;
|
|
5
|
+
stop?: (stopFn: () => void) => void;
|
|
6
|
+
}
|
|
7
|
+
type SingleResultTuple<T> = [Error | null, T | null, boolean];
|
|
8
|
+
type MultipleResultTuple<T> = [(Error | null)[], (T | null)[], boolean];
|
|
9
|
+
type Result<T, I> = I extends Array<any> ? MultipleResultTuple<T> : SingleResultTuple<T>;
|
|
10
|
+
/**
|
|
11
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
12
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
13
|
+
* @param {Object} options - 配置选项
|
|
14
|
+
* @param {number} options.limit - 并发限制默认10
|
|
15
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
16
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
17
|
+
* @example
|
|
18
|
+
*
|
|
19
|
+
// 示例方法:返回 Promise 的函数
|
|
20
|
+
function exampleAsyncFunction() {
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
setTimeout(() => {
|
|
23
|
+
const isSuccess = Math.random() > 0.5;
|
|
24
|
+
if (isSuccess) {
|
|
25
|
+
resolve('Success data');
|
|
26
|
+
} else {
|
|
27
|
+
reject(new Error('Something went wrong'));
|
|
28
|
+
}
|
|
29
|
+
}, 1000);
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 使用封装的 nsPromise 方法
|
|
34
|
+
(async () => {
|
|
35
|
+
const [err, result, isStopped] = await nsPromise(
|
|
36
|
+
exampleAsyncFunction,
|
|
37
|
+
{
|
|
38
|
+
limit: 10, // 控制并发数量
|
|
39
|
+
stop: (stopExecution) => {
|
|
40
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
console.log('Error:', err);//Error: null
|
|
46
|
+
console.log('Result:', result);//Result: null
|
|
47
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
48
|
+
|
|
49
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
50
|
+
[
|
|
51
|
+
exampleAsyncFunction,
|
|
52
|
+
exampleAsyncFunction,
|
|
53
|
+
exampleAsyncFunction,
|
|
54
|
+
exampleAsyncFunction,
|
|
55
|
+
exampleAsyncFunction,
|
|
56
|
+
exampleAsyncFunction,
|
|
57
|
+
exampleAsyncFunction,
|
|
58
|
+
exampleAsyncFunction,
|
|
59
|
+
],
|
|
60
|
+
{
|
|
61
|
+
limit: 10, // 控制并发数量
|
|
62
|
+
stop: (stopExecution) => {
|
|
63
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
69
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
70
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
71
|
+
})();
|
|
72
|
+
*/
|
|
73
|
+
declare function nsPromiseFn<T = any, I = PromiseInput<T>>(input: I, options?: Options): Promise<Result<T, I>>;
|
|
74
|
+
export default nsPromiseFn;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
/**
|
|
7
|
+
* 封装多个 Promise 方法,返回 [错误, 数据, 停止状态] 格式
|
|
8
|
+
* @param {Array<Function | Promise> | Function | Promise} input - 返回 Promise 的函数数组或 Promise 数组,或者单个函数或 Promise
|
|
9
|
+
* @param {Object} options - 配置选项
|
|
10
|
+
* @param {number} options.limit - 并发限制默认10
|
|
11
|
+
* @param {Function} options.stop - 停止函数的回调
|
|
12
|
+
* @returns {Promise<Array>} [err, result, isStop]
|
|
13
|
+
* @example
|
|
14
|
+
*
|
|
15
|
+
// 示例方法:返回 Promise 的函数
|
|
16
|
+
function exampleAsyncFunction() {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
setTimeout(() => {
|
|
19
|
+
const isSuccess = Math.random() > 0.5;
|
|
20
|
+
if (isSuccess) {
|
|
21
|
+
resolve('Success data');
|
|
22
|
+
} else {
|
|
23
|
+
reject(new Error('Something went wrong'));
|
|
24
|
+
}
|
|
25
|
+
}, 1000);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// 使用封装的 nsPromise 方法
|
|
30
|
+
(async () => {
|
|
31
|
+
const [err, result, isStopped] = await nsPromise(
|
|
32
|
+
exampleAsyncFunction,
|
|
33
|
+
{
|
|
34
|
+
limit: 10, // 控制并发数量
|
|
35
|
+
stop: (stopExecution) => {
|
|
36
|
+
setTimeout(stopExecution, 500); // 0.5秒后停止
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
console.log('Error:', err);//Error: null
|
|
42
|
+
console.log('Result:', result);//Result: null
|
|
43
|
+
console.log('Is Stopped:', isStopped);//Is Stopped: true
|
|
44
|
+
|
|
45
|
+
const [arrayErr, arrayResults, arrayIsStopped] = await nsPromise(
|
|
46
|
+
[
|
|
47
|
+
exampleAsyncFunction,
|
|
48
|
+
exampleAsyncFunction,
|
|
49
|
+
exampleAsyncFunction,
|
|
50
|
+
exampleAsyncFunction,
|
|
51
|
+
exampleAsyncFunction,
|
|
52
|
+
exampleAsyncFunction,
|
|
53
|
+
exampleAsyncFunction,
|
|
54
|
+
exampleAsyncFunction,
|
|
55
|
+
],
|
|
56
|
+
{
|
|
57
|
+
limit: 10, // 控制并发数量
|
|
58
|
+
stop: (stopExecution) => {
|
|
59
|
+
setTimeout(stopExecution, 10000); // 10秒后停止
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
console.log('Array Errors:', arrayErr);//Array Errors: (8) [null, Error: Direct promise failure at <anonymous>:117:58, null, Error: Something went wrong at <anonymous>:86:16, Error: Something went wrong at <anonymous>:86:16, null, null, null]
|
|
65
|
+
console.log('Array Results:', arrayResults); //Array Results: (8) ["Direct promise success", null, "Success data", null, null, "Success data", "Success data", "Success data"]
|
|
66
|
+
console.log('Array Is Stopped:', arrayIsStopped); //Array Is Stopped: false
|
|
67
|
+
})();
|
|
68
|
+
*/
|
|
69
|
+
function nsPromiseFn(input, options) {
|
|
70
|
+
if (options === void 0) {
|
|
71
|
+
options = {};
|
|
72
|
+
}
|
|
73
|
+
var _a = options.limit,
|
|
74
|
+
limit = _a === void 0 ? 10 : _a,
|
|
75
|
+
stop = options.stop;
|
|
76
|
+
var isStopped = false;
|
|
77
|
+
var activePromises = 0;
|
|
78
|
+
var currentIndex = 0;
|
|
79
|
+
var results = [];
|
|
80
|
+
var errors = [];
|
|
81
|
+
var isArrayInput = Array.isArray(input);
|
|
82
|
+
var promiseFunctions = isArrayInput ? input : [input];
|
|
83
|
+
var stopPromise = new Promise(function (_, reject) {
|
|
84
|
+
stop === null || stop === void 0 ? void 0 : stop(function () {
|
|
85
|
+
isStopped = true;
|
|
86
|
+
reject(new Error('Stopped'));
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
return new Promise(function (resolve) {
|
|
90
|
+
var executeNext = function executeNext() {
|
|
91
|
+
var _a, _b;
|
|
92
|
+
if (currentIndex >= promiseFunctions.length && activePromises === 0) {
|
|
93
|
+
if (isArrayInput) {
|
|
94
|
+
resolve([errors, results, isStopped]);
|
|
95
|
+
} else {
|
|
96
|
+
resolve([(_a = errors[0]) !== null && _a !== void 0 ? _a : null, (_b = results[0]) !== null && _b !== void 0 ? _b : null, isStopped]);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
while (activePromises < limit && currentIndex < promiseFunctions.length) {
|
|
101
|
+
var current = promiseFunctions[currentIndex];
|
|
102
|
+
currentIndex += 1;
|
|
103
|
+
activePromises += 1;
|
|
104
|
+
var promise = typeof current === 'function' ? current() : current;
|
|
105
|
+
Promise.race([promise, stopPromise]).then(function (data) {
|
|
106
|
+
if (!isStopped) {
|
|
107
|
+
results.push(data);
|
|
108
|
+
errors.push(null);
|
|
109
|
+
}
|
|
110
|
+
}).catch(function (err) {
|
|
111
|
+
if (!isStopped || err.message === 'Stopped') {
|
|
112
|
+
results.push(null);
|
|
113
|
+
errors.push(err);
|
|
114
|
+
}
|
|
115
|
+
}).finally(function () {
|
|
116
|
+
var _a, _b;
|
|
117
|
+
activePromises -= 1;
|
|
118
|
+
if (!isStopped) {
|
|
119
|
+
executeNext();
|
|
120
|
+
} else if (activePromises === 0) {
|
|
121
|
+
if (isArrayInput) {
|
|
122
|
+
resolve([errors, results, isStopped]);
|
|
123
|
+
} else {
|
|
124
|
+
resolve([(_a = errors[0]) !== null && _a !== void 0 ? _a : null, (_b = results[0]) !== null && _b !== void 0 ? _b : null, isStopped]);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
executeNext();
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
exports.default = nsPromiseFn;
|