promise本身不支持优先级调度,需结合最大堆管理任务权重、队列串行执行器控制执行顺序,通过add入堆、run串行await高权任务实现“高权重先执行”。

理解带权重的异步任务队列核心逻辑
Promise 本身不直接支持优先级调度,但可以结合数据结构(如最小堆或排序数组)+ 队列管理 + Promise 链式控制,实现“高权重任务先执行”的效果。关键不是改 Promise,而是控制 谁被 nextTick 或 setTimeout 排队执行,以及 何时调用 task() 并 await 其返回的 Promise。
用最小堆维护任务优先级(推荐)
权重越高越优先 → 可定义为“优先级值越大,越先出队”。用最小堆反向处理(存 -weight),或直接用最大堆逻辑(JavaScript 无原生最大堆,手动维护即可)。下面是一个轻量、可运行的实现:
// 简单最大堆(基于数组,按 weight 降序)
class MaxHeap {
constructor() {
this.heap = [];
}
push(task) {
this.heap.push(task);
this._heapifyUp(this.heap.length - 1);
}
pop() {
if (this.heap.length === 0) return null;
const top = this.heap[0];
const last = this.heap.pop();
if (this.heap.length > 0) {
this.heap[0] = last;
this._heapifyDown(0);
}
return top;
}
_heapifyUp(i) {
while (i > 0) {
const parent = Math.floor((i - 1) / 2);
if (this.heap[i].weight this.heap[largest].weight) {
largest = left;
}
if (right this.heap[largest].weight) {
largest = right;
}
if (largest === i) break;
[this.heap[i], this.heap[largest]] = [this.heap[largest], this.heap[i]];
i = largest;
}
}
}
封装带权重的 Promise 任务队列
核心是:不立即执行任务函数,而是入堆;由一个串行执行器(run 方法)持续取最高权任务并 await 其 Promise。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 每个任务是形如
{ weight: number, fn: () => Promise<any> }</any>的对象 - 入队用
add(task),自动按 weight 堆化 - 执行器用
run()启动,自动串行消费,支持暂停/恢复(可选) - 可链式返回 Promise,方便外层 await 队列整体完成
// 完整队列类示例
class PriorityTaskQueue {
constructor() {
this.heap = new MaxHeap();
this.running = false;
}
<p>add({ weight = 0, fn }) {
if (typeof fn !== 'function') throw new Error('task.fn must be a function');
this.heap.push({ weight, fn });
}</p><p>async run() {
if (this.running) return;
this.running = true;</p><pre class="brush:php;toolbar:false;">while (this.heap.heap.length > 0) {
const task = this.heap.pop();
try {
await task.fn(); // 等待当前最高权任务完成
} catch (err) {
console.warn('Task failed (ignored):', err);
}
}
this.running = false;}
// 可选:清空未执行任务 clear() { this.heap = new MaxHeap(); } }
// 使用示例: const queue = new PriorityTaskQueue();
queue.add({ weight: 10, fn: () => new Promise(r => setTimeout(() => { console.log('high-pri'); r(); }, 100)) });
queue.add({ weight: 1, fn: () => new Promise(r => setTimeout(() => { console.log('low-pri'); r(); }, 50)) });
queue.add({ weight: 5, fn: () => new Promise(r => setTimeout(() => { console.log('mid-pri'); r(); }, 80)) });
queue.run(); // 输出顺序:high-pri → mid-pri → low-pri
注意边界与增强点
- 相同权重任务:堆内顺序不确定,如需 FIFO 补充插入时间戳,比较时加二级排序
- 动态权重调整:堆不支持高效 update,建议移除旧任务 + 新增更高权任务(或重建堆)
- 并发执行 N 个高权任务:可扩展为「按权重分组 + 每组内 Promise.all」,而非严格串行
- 取消任务:需在 fn 中支持 AbortSignal,Promise 无法原生取消,靠业务逻辑配合
- 内存泄漏防范:避免长期持有大量未执行 task.fn 引用,尤其闭包大对象
不复杂但容易忽略细节。重点是把“调度权”从事件循环手里拿回来,交给你自己写的队列和堆。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










