






















@@ -61,6 +61,8 @@ type QueueEntry = {
6161resolve: (value: unknown) => void;
6262reject: (reason?: unknown) => void;
6363enqueuedAt: number;
64+sequence: number;
65+priority: number;
6466warnAfterMs: number;
6567taskTimeoutMs?: number;
6668taskTimeoutProgressAtMs?: () => number | undefined;
@@ -107,6 +109,7 @@ function getQueueState() {
107109lanes: new Map<string, LaneState>(),
108110activeTaskWaiters: new Set<ActiveTaskWaiter>(),
109111nextTaskId: 1,
112+nextQueueSequence: 1,
110113}));
111114// Schema migration: the singleton may have been created by an older code
112115// version (e.g. v2026.4.2) that did not include `activeTaskWaiters`. After
@@ -117,6 +120,27 @@ function getQueueState() {
117120if (!state.activeTaskWaiters) {
118121state.activeTaskWaiters = new Set<ActiveTaskWaiter>();
119122}
123+if (!state.nextQueueSequence) {
124+state.nextQueueSequence = 1;
125+}
126+let maxQueueSequence = state.nextQueueSequence - 1;
127+for (const lane of state.lanes.values()) {
128+for (const entry of lane.queue as Array<
129+QueueEntry & { priority?: number; sequence?: number }
130+>) {
131+if (typeof entry.priority !== "number") {
132+entry.priority = 0;
133+}
134+if (typeof entry.sequence !== "number") {
135+entry.sequence = state.nextQueueSequence++;
136+} else {
137+maxQueueSequence = Math.max(maxQueueSequence, entry.sequence);
138+}
139+}
140+}
141+if (state.nextQueueSequence <= maxQueueSequence) {
142+state.nextQueueSequence = maxQueueSequence + 1;
143+}
120144return state;
121145}
122146@@ -204,6 +228,30 @@ function normalizeTaskTimeoutMs(value: number | undefined): number | undefined {
204228return Math.max(1, Math.floor(value));
205229}
206230231+function resolveQueuePriority(priority: CommandQueueEnqueueOptions["priority"]): number {
232+switch (priority) {
233+case "foreground":
234+return 1;
235+case "background":
236+return -1;
237+default:
238+return 0;
239+}
240+}
241+242+function enqueueLaneEntry(state: LaneState, entry: QueueEntry): void {
243+const insertAt = state.queue.findIndex(
244+(queued) =>
245+queued.priority < entry.priority ||
246+(queued.priority === entry.priority && queued.sequence > entry.sequence),
247+);
248+if (insertAt < 0) {
249+state.queue.push(entry);
250+return;
251+}
252+state.queue.splice(insertAt, 0, entry);
253+}
254+207255async function runQueueEntryTask(lane: string, entry: QueueEntry): Promise<unknown> {
208256const taskPromise = Promise.resolve().then(entry.task);
209257const taskTimeoutMs = normalizeTaskTimeoutMs(entry.taskTimeoutMs);
@@ -362,11 +410,13 @@ export function enqueueCommandInLane<T>(
362410const warnAfterMs = opts?.warnAfterMs ?? 2_000;
363411const state = getLaneState(cleaned);
364412return new Promise<T>((resolve, reject) => {
365-state.queue.push({
413+enqueueLaneEntry(state, {
366414task: () => task(),
367415resolve: (value) => resolve(value as T),
368416 reject,
369417enqueuedAt: Date.now(),
418+sequence: queueState.nextQueueSequence++,
419+priority: resolveQueuePriority(opts?.priority),
370420 warnAfterMs,
371421taskTimeoutMs: normalizeTaskTimeoutMs(opts?.taskTimeoutMs),
372422taskTimeoutProgressAtMs: opts?.taskTimeoutProgressAtMs,
@@ -472,6 +522,7 @@ export function resetCommandQueueStateForTest(): void {
472522resolveActiveTaskWaiter(waiter, { drained: true });
473523}
474524queueState.nextTaskId = 1;
525+queueState.nextQueueSequence = 1;
475526}
476527477528/**
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。