2024-10-28 18:38:11 +08:00
|
|
|
|
import { escapeRegExp } from "lodash";
|
2024-08-03 12:46:12 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 检查字符串中是不是包含中文或者标点符号
|
|
|
|
|
|
* @param str 需要判断的字符串
|
|
|
|
|
|
* @returns 返回的数据,有中文或者标点符号返回true,否则返回false
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function ContainsChineseOrPunctuation(str: string): boolean {
|
|
|
|
|
|
return /[\u4e00-\u9fa5]|[\u3000-\u301e\u2013\u2014\u2018\u2019\u201c\u201d\u2026\u203b\uff08\uff09\uff1a\uff1b\uff1f\uff01\uff0c\u3001\uff0e\u3002\uff1f\uff01\u2018\u2019\u201c\u201d]/.test(
|
|
|
|
|
|
str
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
2024-08-20 10:37:38 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 通用的重试函数
|
|
|
|
|
|
* @param fn 要执行的函数
|
|
|
|
|
|
* @param retries 最大重试次数
|
|
|
|
|
|
* @param delay 每次重试之间的延迟(毫秒)
|
|
|
|
|
|
* @returns 返回函数的结果
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function RetryWithBackoff<T>(fn: () => Promise<T>, retries: number = 5, delay: number = 2000): Promise<T> {
|
|
|
|
|
|
let attempts = 0;
|
|
|
|
|
|
while (attempts < retries) {
|
|
|
|
|
|
try {
|
|
|
|
|
|
return await fn();
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
attempts++;
|
|
|
|
|
|
// 这边记下日志吧
|
|
|
|
|
|
global.logger.error(
|
|
|
|
|
|
fn.name + '_RetryWithBackoff',
|
|
|
|
|
|
`第 ${attempts} 请求失败,开始下一次重试,失败信息如下:` + error.toString()
|
|
|
|
|
|
)
|
|
|
|
|
|
if (attempts >= retries) {
|
|
|
|
|
|
throw new Error(`失败次数超过 ${retries} 错误信息如下: ${error.message}`);
|
|
|
|
|
|
}
|
|
|
|
|
|
await new Promise(resolve => setTimeout(resolve, delay));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
throw new Error('所有重试失败'); // 理论上不会到达这里
|
|
|
|
|
|
}
|
2024-09-12 14:13:09 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 并发执行任务(控制同时执行的任务数)
|
|
|
|
|
|
* @param tasks 总的任务列表
|
|
|
|
|
|
* @param concurrentCount 同时执行的数量
|
|
|
|
|
|
* @returns
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function ExecuteConcurrently(tasks: Array<() => Promise<any>>, concurrentCount: number): Promise<any[]> {
|
|
|
|
|
|
let activeTasks: Array<Promise<any>> = [];
|
|
|
|
|
|
let results: Array<Promise<any>> = [];
|
|
|
|
|
|
|
|
|
|
|
|
while (tasks.length > 0) {
|
|
|
|
|
|
if (activeTasks.length < concurrentCount) {
|
|
|
|
|
|
let task = tasks.shift();
|
|
|
|
|
|
let promise = task().then(result => {
|
|
|
|
|
|
activeTasks = activeTasks.filter(t => t !== promise);
|
|
|
|
|
|
return result;
|
|
|
|
|
|
}).catch(error => {
|
|
|
|
|
|
// 抛出任务,停止所有的任务
|
|
|
|
|
|
tasks.length = 0;
|
|
|
|
|
|
throw error
|
|
|
|
|
|
});
|
|
|
|
|
|
activeTasks.push(promise);
|
|
|
|
|
|
results.push(promise);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await Promise.race(activeTasks);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return Promise.all(results);
|
2024-10-28 18:38:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 替换主字符串中的子字符串
|
|
|
|
|
|
* @param mainString 主字符串
|
|
|
|
|
|
* @param substringArray 子字符串数组
|
|
|
|
|
|
* @returns 替换后的字符串
|
|
|
|
|
|
*/
|
|
|
|
|
|
export function ReplaceSubstrings(mainString: string, substringArray: string[], replacement: string = " "): string {
|
|
|
|
|
|
// 按长度降序排序子字符串数组,以确保较长的子字符串先被替换
|
|
|
|
|
|
substringArray.sort((a, b) => b.length - a.length);
|
|
|
|
|
|
|
|
|
|
|
|
// 对每个子字符串进行替换
|
|
|
|
|
|
for (const substring of substringArray) {
|
|
|
|
|
|
// 创建一个正则表达式,用于全局匹配子字符串
|
|
|
|
|
|
const regex = new RegExp(escapeRegExp(substring), 'g');
|
|
|
|
|
|
// 将匹配到的子字符串替换为等长的空格
|
|
|
|
|
|
mainString = mainString.replace(regex, replacement);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return mainString;
|
2024-09-12 14:13:09 +08:00
|
|
|
|
}
|