【js】带并发控制和重试机制的请求

const withRetry = async<T>(
	fn: (signal?: AbortSignal) => Promise<T>
	retries=3,
	delay=1000,
	params?: any,
	signal?: AbortSignal,
) => {
	try {
		// 检查是否已取消请求
		if(signal?.aborted) {
			return {
				status: 'networdError',
				error: {
					message: '请求已取消',
					params
				},
				params,
			};
		}
		const result = await fn(signal);
		return {
			status: 'success',
			data: result,
			params
		};
	}catch(error) {
		if(signal?.aborted || retries < 0) {
			const errorMsg = signal?.aborted ? '请求已取消'
			 : error?.message || '请求失败,已达最大重试次数';
		 	return {
				status: 'newworkError',
				error: {
					message: errorMsg,
					code: error?.code,
					retries: 3-retries,
					params,
				},
				params,
			}
		}
		
		const retryDelay = delay * Math.pow(2, 3 - retries);
		await new Promise(resolve => setTimeout(resolve, retryDelay));
		// 递归调用,减少重试次数
		return withRetry(fn, retries-1, delay, params, signal);		
	}
};
const batchPromise = async <T>(
	tasks: Array<() => Promise<T>>,
	batchSize: number = 5
): Promise<T[]> => {
	const results: T[] = [];
	// 分批处理任务
	for(let i = 0; i< tasks.length; i += batchSize) {
		const batch = tasks.slice(i, i + batchSize);
		const batchResults = await Promise.allSettled(batch.map(task => task()));
		// 收集结果
		batchResults.forEach(result => {
			if(result.status === 'fulfilled') {
				results.push(result.value);
			}else {
				console.log(result.reason);
			}
		});
	}
	return results;
}
const queryAllList = () => {
	// 创建取消控制器(如果为传入)
	const controller = abortController || new AbortController();
	const {signal} = controller;
	// 创建所有请求任务
	const tasks = groups.map(item => {
		return () => withRetry(
			(reqSignal) => listApi({
				params1: item.params1,
				params2: item.params2,
				signal: reqSignal
			}).then(res => {
				if(res.code === 200) {
					return { ...res.data };
				}else {
					const error = new Error(`业务错误: ${res.msg || '未知错误'}`);
					error.code = res.code;
					throw error;
				}
			}),
			3, 
			1000,
			item,	// 记录请求参数
			signal	// 是否取消请求的信号
			);
	});
	const results = await Promise.all(tasks);  // 不带并发控制的
	// 带并发控制的,限制并发数量(每批最多5个请求)
	const results = await batchPromise(tasks, 5);	
	return results.filter(Boolean);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值