From 8c949b491677e86f7e0f652e3356de92eae2a0b6 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Sun, 7 Aug 2022 02:57:46 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E6=80=A7=E8=83=BD=E4=BC=98=E5=8C=96:?= =?UTF-8?q?=20getUserInfo=E6=8E=A5=E5=8F=A3=E8=AF=B7=E6=B1=82=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=90=88=E5=B9=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- shared/cache/cache.ts | 1 - shared/model/user.ts | 19 ++++++++++----- shared/utils/request.ts | 53 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 7 deletions(-) create mode 100644 shared/utils/request.ts 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, + }); + }); + }; +}