优化 requestUserProfile 并发请求
requestUserProfile 是个通用查询用户信息接口,通过传入 uid ,拿用户昵称 在一个支付宝群聊里有 10 多个用户,点击群聊信息,展示各个人的昵称 10 个并发请求,会阻塞接口 10 个依次请求,耗时久,显示昵称太慢 需要优化请求,在并发和耗时之间掌握一个平衡
// 核心用户请求
let _requestTime = 0;
const requestProfile = (uid: string) => {
// 这个方法的实现不能修改
return Promise.resolve().then(() => {
return new Promise<void>((resolve) => {
setTimeout(() => {
// 模拟 ajax 异步,1s 返回
resolve();
}, 1000);
}).then(() => {
_requestTime++;
return {
uid,
nick: `nick-${uid}`,
age: "18",
};
});
});
};
/**
*
* @param uid uid
* @param max 最多并发请求数量
*/
const requestUserProfile = (uid, max = 2) => {}
1
ChefIsAwesome 2023-05-31 23:02:08 +08:00 via Android
可以再加几种变化:
重试请求。失败的请求插到队列尾重试或者插到下一组重试,重试 n 次之后报错。 按顺序显示结果。比方说并发的 1 、2 个请求,返回顺序是 2 、1 。要求 2 返回时不处理,1 返回时再依次处理 1 、2 。 延迟。并发的一组结束之后,等待一段时间再开始下一组。 |
2
gromit1337 OP @ChefIsAwesome 有测试用例的
```javascript export default async () => { try { const star = Date.now(); const result = await Promise.all([ requestUserProfile("1"), requestUserProfile("2"), requestUserProfile("3"), requestUserProfile("1"), ]); if (Date.now() - star < 2000 || Date.now() - star >= 3000) { throw new Error("Wrong answer"); } if ( !isEqual(result, [ { uid: "1", nick: "nick-1", age: "18", }, { uid: "2", nick: "nick-2", age: "18", }, { uid: "3", nick: "nick-3", age: "18", }, { uid: "1", nick: "nick-1", age: "18", }, ]) ) { throw new Error("Wrong answer"); } return _requestTime === 3; } catch (err) { console.warn("测试运行失败"); console.error(err); return false; } }; ``` |
3
uncat 2023-06-01 10:24:24 +08:00 1
|
4
uncat 2023-06-01 10:48:33 +08:00
|
5
zhy0216 2023-06-02 10:19:47 +08:00
|
6
zhy0216 2023-06-02 12:08:31 +08:00
```ts
/** * * @param uid uid * @param max 最多并发请求数量 */ const queue: (() => unknown)[] = []; let activeCount = 0; let queueCursor = 0; const requestUserProfile = (uid: string, max = 2) => { return new Promise((resolve) => { const runF = async () => { activeCount++; const r = await requestProfile(uid); activeCount--; if (queueCursor < queue.length) { queue[queueCursor++](); } return resolve(r); }; queue.push(runF); if (activeCount < max) { queue[queueCursor++](); } }); }; ``` |