面试题实现网络请求并发限制的管理类
代码地址 /example/net-manager/net-manager.html
背景
2020 年阿里的一个面试题(我自己面试被问过的)
掘金地址: https://juejin.cn/post/6907265963016912909
题目:
实现网络请求并发限制的管理类 NetManager(concurrency), 构造函数传入一个 number,是并发的限制数, 提供 request(url, data) => Promise<res>
方法
javascript
// 实现网络请求并发限制的管理类 NetManager(concurrency),
// 构造函数传入一个number,是并发的限制数,
// 提供 request(url, data) => Promise<res> 方法
// Const obj = new NetManager(5)
// obj.request(“/xxx/sss”, {a: 1})
// net-manager.js
class NetManager {
constructor(number) {
if (!(typeof number === 'number' && !Number.isNaN(number))) {
console.error(`NetManager params typeof number === '${typeof number}', value: ${number}`);
}
this.number = number;
this.queues = [];
this.caches = [];
}
trigger = () => {
const hits = this.queues.filter((i) => i.isFetch === false);
hits.forEach((item) => {
item.isFetch = true;
item
.task()
.then(item.resolve)
.catch(item.reject)
.finally(() => {
const deleteIndex = this.queues.findIndex((del) => del.key === item.key);
if (deleteIndex !== -1) {
this.queues.splice(deleteIndex, 1);
}
if (this.caches.length > 0) {
this.queues.push(this.caches.shift());
this.trigger();
}
});
});
};
request = (...reset) => {
return new Promise((resolve, reject) => {
// 绑定一个函数并传参
const task = window.fetch.bind(null, ...reset);
// 生成一个key值,用于删除队列任务
const key = Math.random();
const newItem = {key, isFetch: false, task, resolve, reject};
if (this.queues.length >= this.number || this.caches.length > 0) {
this.caches.push(newItem);
} else {
this.queues.push(newItem);
this.trigger();
}
});
};
}
const JSON_PLACEHOLDER = 'https://jsonplaceholder.typicode.com/todos/';
const obj = new NetManager(2);
for (let i = 1; i <= 10; i++) {
obj
.request(`${JSON_PLACEHOLDER}${i}`, {credentials: 'include'})
.then((res) => res.json())
.then((result) => {
console.log('result', result);
})
.catch((err) => {
console.error(err);
});
}
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script src="./net-manager.js"></script>
</body>
</html>
这道题考察什么?
序号 | 描述 |
---|---|
1 | Promise 应用 |
2 | 逻辑思维能力(算法) |
3 | 工作经验 |
队列任务
批量任务、有规律、有逻辑的执行的时候需要用到
序号 | 描述 | |
---|---|---|
1 | 批量文件上传 | 文件切片,批量图片上传(聊天) |
2 | 多任务相互依赖 | 比如有三个请求,1、2 和 3,请求 2 依赖 1 3 依赖 2。 |
3 | 表单校验 | 多个异步校验表单 |
4 | 发送消息 | 保证消息发送顺序,接收顺序 |
5 | 计数器 | 聊天软件未读数、已读数、表情回复 |
6 | http 并发请求限制 |
NetManager 类扩展
序号 | 方法 | 类型 | 描述 |
---|---|---|---|
1 | push | 增加 | 可以增加任务 |
2 | remove | 移除 | 移除未执行的 Promise,终止正在执行的 Promise |
3 | update | 修改,排序 | 调整优先级,比如下载任务的时候,我希望用户看到的区域的图片有限下载 |
4 | find | 查询 | 比如进入会话自动下载图片,先查询是否存在队列,不存在继续下载 |