Skip to content
扫码开始移动端阅读
合并重复请求
共
537
字 需要≈
2.685
分钟 手撕面试题
JavaScript
为什么有这个需求?
TIP
比如我有一个获取用户信息的接口,在屎山代码中,可能很多地方都调用了这个接口,恰好,这个优雅的后端连用户信息接口也要返回很久的时候。项目在多个地方使用了这个接口的返回值,这个时候我们就会发现,在页面加载的时候,会出现很多个请求。这样就可以优化成一个请求。
代码
js
import md5 from 'md5';
class TaskQueue {
constructor() {
this.taskQueue = new Map(); // 任务队列,用于存储任务ID和任务信息
}
// 生成任务ID的函数,使用url、method和data生成MD5哈希
createTaskId(url, method, data) {
return md5(`${url}-${method}-${JSON.stringify(data)}`);
}
// 核心方法,返回一个Promise
fetchWithTaskQueue(url, method, data) {
return new Promise((resolve, reject) => {
const taskId = this.createTaskId(url, method, data);
// 检查任务队列中是否已有相同任务
if (this.taskQueue.has(taskId)) {
const existingTask = this.taskQueue.get(taskId);
if (!existingTask.isCompleted) {
// 如果任务已存在且未完成,观察该任务
existingTask.promise.then(resolve).catch(reject);
return;
}
}
// 创建新的任务
const newTask = {
isCompleted: false,
promise: null,
resolve: null,
reject: null
};
// 创建任务的Promise
newTask.promise = new Promise((resolveTask, rejectTask) => {
newTask.resolve = resolveTask;
newTask.reject = rejectTask;
});
// 将新任务加入任务队列
this.taskQueue.set(taskId, newTask);
// 发送请求
fetch(url, {
method: method,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(result => {
// 请求成功时,设置任务完成状态,触发resolve,并删除任务
newTask.isCompleted = true;
newTask.resolve(result);
this.taskQueue.delete(taskId);
resolve(result);
})
.catch(error => {
// 请求失败时,设置任务完成状态,触发reject,并删除任务
newTask.isCompleted = true;
newTask.reject(error);
this.taskQueue.delete(taskId);
reject(error);
});
});
}
}
export default TaskQueue;
解析
- 用md5生成一个唯一的id,然后判断这个任务是否已经存在了,如果存在,则直接观察这个任务,如果不存在,则创建一个新的任务,然后发送请求。
- 请求成功时,设置任务完成状态,触发resolve,并删除任务。
- 请求失败时,设置任务完成状态,触发reject,并删除任务。
结尾
我们需要多思考,多总结。才能让我们的代码能更好的服务于我们的业务。
转载请注明来源:LeeDaisen : 《合并重复请求》