diff --git a/shared/cache/cache.ts b/shared/cache/cache.ts index 54cfd9f2..3d158916 100644 --- a/shared/cache/cache.ts +++ b/shared/cache/cache.ts @@ -1,4 +1,3 @@ -import { getServiceUrl } from '../manager/service'; import { ChatConverseInfo, fetchConverseInfo } from '../model/converse'; import { findGroupInviteByCode, GroupInvite } from '../model/group'; import { diff --git a/shared/model/user.ts b/shared/model/user.ts index cd774f50..4285f44f 100644 --- a/shared/model/user.ts +++ b/shared/model/user.ts @@ -1,6 +1,7 @@ import { request } from '../api/request'; import { buildCachedRequest } from '../cache/utils'; import { SYSTEM_USERID } from '../utils/consts'; +import { createAutoMergedRequest } from '../utils/request'; export interface UserBaseInfo { _id: string; @@ -173,6 +174,16 @@ export async function searchUserWithUniqueName( return data; } +const _fetchUserInfo = createAutoMergedRequest( + async (userIds) => { + // 这里用post是为了防止一次性获取的userId过多超过url限制 + const { data } = await request.post('/api/user/getUserInfoList', { + userIds, + }); + + return data; + } +); /** * 获取用户基本信息 * @param userId 用户ID @@ -182,13 +193,9 @@ export async function fetchUserInfo(userId: string): Promise { return builtinUserInfo[userId]; } - const { data } = await request.get('/api/user/getUserInfo', { - params: { - userId, - }, - }); + const userInfo = await _fetchUserInfo(userId); - return data; + return userInfo; } /** diff --git a/shared/utils/request.ts b/shared/utils/request.ts new file mode 100644 index 00000000..63add8e1 --- /dev/null +++ b/shared/utils/request.ts @@ -0,0 +1,53 @@ +interface QueueItem { + params: T; + resolve: (r: R) => void; + reject: (reason: any) => void; +} + +/** + * 创建一个自动合并请求的函数 + * 在一定窗口期内的所有请求都会被合并提交合并发送 + * @param fn 合并后的请求函数 + * @param windowMs 窗口期 + */ +export function createAutoMergedRequest( + fn: (mergedParams: T[]) => Promise, + windowMs = 200 +): (params: T) => Promise { + let queue: QueueItem[] = []; + let timer: number; + + async function submitQueue() { + const _queue = [...queue]; + queue = []; // 清空队列 + const ret = fn(_queue.map((q) => q.params)); + + try { + const list = await ret; + _queue.forEach((q_1, i) => { + q_1.resolve(list[i]); + }); + } catch (err) { + _queue.forEach((q_2) => { + q_2.reject(err); + }); + } + } + + return (params: T): Promise => { + if (!timer) { + // 如果没有开始窗口期,则创建 + timer = window.setTimeout(() => { + submitQueue(); + }, windowMs); + } + + return new Promise((resolve, reject) => { + queue.push({ + params, + resolve, + reject, + }); + }); + }; +}