前端优先级请求队列需用可排序结构(如数组或最小堆)管理请求,按priority升序调度,支持并发控制、动态插队(如pushHigh)、取消(cancelToken)及Promise交还。

在前端实现支持按优先级排序的请求队列,核心是用一个可排序的数据结构(如数组或最小堆)管理待发请求,并配合一个执行器控制并发与调度。关键不是“先到先得”,而是“高优先发、低优等待、可取消、可动态插队”。
用优先队列结构管理请求
JavaScript 原生没有优先队列,但可用数组 + sort() 模拟(适合中低并发),或手动实现最小堆(适合高频/大量请求)。每个请求对象需携带:id、fn(实际请求函数)、priority(数值越小优先级越高,如 0=最高)、cancelToken(用于取消)、resolve/reject(Promise 控制权)。
插入新请求时,直接 push 进数组,然后按 priority 升序重排:
requests.push({ fn, priority, resolve, reject, id });
requests.sort((a, b) => a.priority - b.priority);带并发控制的执行器
不能一次性全发,需限制同时进行的请求数(如最多 3 个)。维护一个运行中计数器 activeCount,每次有空位就从队首取最高优请求执行:
立即学习“Java免费学习笔记(深入)”;
- 执行前检查是否已被取消(通过
cancelToken?.aborted) - 用
fn().then(resolve).catch(reject)转交结果 - 完成后
activeCount--,并立即尝试调度下一个 - 若队列非空且有空位,递归调用调度函数
支持动态插队与取消
用户操作可能临时提升某请求优先级(如用户点击搜索框立刻查热门词),这时不能等它自然轮到——要允许「插队」:
- 提供
queue.pushHigh(request)方法,插入时设priority: -1或更低 - 提供
queue.cancel(id),遍历队列匹配id并移除;若已在执行中,调用其abortController.abort() - 取消后记得触发对应
reject(new Error('canceled')),避免 Promise 悬停
封装成易用的类(精简示例)
以下是一个轻量实用的实现骨架:
class PriorityQueue {
constructor(maxConcurrent = 3) {
this.requests = [];
this.activeCount = 0;
this.maxConcurrent = maxConcurrent;
}
<p>add(fn, priority = 0) {
const controller = new AbortController();
const promise = new Promise((resolve, reject) => {
this.requests.push({ fn, priority, resolve, reject, id: Math.random(), controller });
this.requests.sort((a, b) => a.priority - b.priority);
this.schedule();
});
return { promise, cancel: () => controller.abort() };
}</p><p>schedule() {
while (this.activeCount < this.maxConcurrent && this.requests.length > 0) {
const req = this.requests.shift();
if (req.controller.signal.aborted) {
req.reject(new Error('canceled'));
continue;
}
this.activeCount++;
req.fn({ signal: req.controller.signal })
.then(req.resolve)
.catch(req.reject)
.finally(() => {
this.activeCount--;
this.schedule();
});
}
}
}使用时:const q = new PriorityQueue(2); const { promise } = q.add(fetchUser, 0);,高优任务传 -10 即可抢占。


















