前言:发这篇文章纯属气不过,有个很爱装X的前端发了个题给我(说这别发给别人),然后我就去写了,写了并没有告诉他答案,隔了5天来找茬。气不过我就写这文章水一篇了(发之前查了这题目去年网上就有了...),发了还被恶意投诉了,CSDN还不给恢复,说什么版权投诉,气死我了。这里再发一遍!!
甚至还有被投诉文章下架,原因:低俗。我真的是 66666 翻了
这样搞迟早不会在CSDN发任何东西
# 要求 - `requestUserProfile` 是个通用用户信息接口,通过传入uid,拿用户昵称 - 在一个群聊里有10多个用户,点击群聊信息,展示各个人的昵称 - 10个并发请求,会阻塞接口 - 10个依次请求,耗时久,显示昵称太慢 - 需要优化请求,在并发和耗时之间掌握一个平衡。
要求:仅优化 requestUserProfile 代码
// 在这里完成代码,进行requestUserProfile优化
// 并且在 requestUserProfile 里调用requestProfile
const requestUserProfile = (uid = '1', max = 2)=> {}
import { isEqual } from "lodash-es";
// 核心用户请求
let _requestTime = 0;
const requestProfile = (uid) => {
// 这个方法的实现不能修改
return Promise.resolve().then(() => {
return new Promise((resolve) => {
setTimeout(() => {
// 模拟 ajax 异步,1s 返回
resolve();
}, 1000);
}).then(() => {
_requestTime++;
return {
uid,
nick: `nick-${uid}`,
age: "18",
};
});
});
};
// 在这里完成代码,进行requestUserProfile优化
// 在这里调用requestProfile
/**
*
* @param uid uid
* @param max 最多并发请求数量
*/
let count = 0;
let wait = [];
const requestUserProfile = async (uid = "1", max = 2) => {
return new Promise((resolve) => {
if (count < max) {
++count;
requestProfile(uid).then((res) => {
--count;
resolve(res);
if (wait.length) {
for (let i = 0; i < wait.length; i++) {
const e = wait[i];
if (count < e.max) {
wait.splice(i, 1);
e.fn();
break;
}
}
}
});
} else {
wait.push({
fn: () => {
requestUserProfile(uid, max).then((res) => {
resolve(res);
});
},
max,
});
}
});
};
/**
* 以下为测试用例,无需修改
*/
export default async function test() {
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");
}
console.log("运行成功,耗时(ms):", Date.now() - star);
return _requestTime === 3;
} catch (err) {
console.warn("测试运行失败");
console.error(err);
return false;
}
}
test();
// 个人追加测试!看log顺序、时间是否正确
requestUserProfile("1", 2).then((res) => {
console.log(res, new Date());
});
requestUserProfile("2", 1).then((res) => {
console.log(res, new Date());
});
requestUserProfile("3", 3).then((res) => {
console.log(res, new Date());
});
requestUserProfile("4", 1).then((res) => {
console.log(res, new Date());
});
requestUserProfile("5", 4).then((res) => {
console.log(res, new Date());
});
requestUserProfile("7", 3).then((res) => {
console.log(res, new Date());
});
requestUserProfile("6", 2).then((res) => {
console.log(res, new Date());
});
requestUserProfile("8", 4).then((res) => {
console.log(res, new Date());
});
requestUserProfile("9", 2).then((res) => {
console.log(res, new Date());
});
requestUserProfile("10", 2).then((res) => {
console.log(res, new Date());
});