const fetchUserInfoBatched = createBatchedRequest<string, UserBaseInfo>( async (userIds) => { const { data } = await request.post('/api/user/list', { userIds, }); return data; }, 500 // 设置延迟时间为500毫秒 ); // 使用示例 async function getUserInfo() { const user1 = await fetchUserInfoBatched(1); const user2 = await fetchUserInfoBatched(2); const user3 = await fetchUserInfoBatched(3); console.log(user1, user2, user3); } getUserInfo();
createBatchedRequest
interface BatchRequestItem<T, R> { params: T; resolve: (r: R) => void; reject: (reason: unknown) => void; } /** * 创建批量请求的函数 * 在一定延迟时间内的所有请求都会被合并提交并批量发送 * @param batchFunction 合并后的请求函数 * @param delay 延迟时间,以毫秒为单位 */ export function createBatchedRequest<T, R>( batchFunction: (batchParams: T[]) => Promise<R[]>, delay = 200 ): (params: T) => Promise<R> { const batchQueue: BatchRequestItem<T, R>[] = []; let isBatching = false; let timer: NodeJS.Timeout | null = null; async function executeBatchedRequest() { if (isBatching) return; isBatching = true; const itemsToBatch = [...batchQueue]; batchQueue.length = 0; try { const batchedResult = await batchFunction(itemsToBatch.map((item) => item.params)); itemsToBatch.forEach((item, index) => { item.resolve(batchedResult[index]); }); } catch (error) { itemsToBatch.forEach((item) => { item.reject(error); }); } finally { isBatching = false; } } return (params: T): Promise<R> => { return new Promise<R>((resolve, reject) => { batchQueue.push({ params, resolve, reject, }); // Execute the batched request after the specified delay if (!timer) { timer = setTimeout(() => { executeBatchedRequest(); timer = null; }, delay); } }); }; }
-
批量请求管理:
createBatchedRequest
函数用于管理批量请求,它可以将多个独立的请求合并成一个批量请求,以减少不必要的网络请求次数。 -
参数说明:
batchFunction
参数是一个函数,接受一个数组batchParams
作为参数,返回一个 Promise,用于处理合并后的请求并返回结果。delay
参数表示延迟时间,以毫秒为单位。在指定的延迟时间内,所有的请求会被收集起来,然后一次性发送给batchFunction
处理。-
请求队列: 函数内部维护一个请求队列
batchQueue
,用于存储待合并的请求项。每个请求项包含了请求的参数、成功回调函数resolve
和失败回调函数reject
。 -
执行批量请求:
- 当有请求调用返回的函数时,它会将请求参数和相应的回调函数添加到请求队列
batchQueue
中。 - 使用定时器控制,在指定的延迟时间后,会执行
executeBatchedRequest
函数。 executeBatchedRequest
函数会检查是否已经有批量请求正在处理(isBatching
标志),如果有,则不进行处理,直到当前批量请求完成。- 如果没有正在处理的批量请求,它会取出请求队列中的所有请求项,合并参数后调用
batchFunction
处理请求。 - 成功或失败后,会分别调用请求项中的
resolve
或reject
回调函数,将结果返回给每个独立的请求。