import { nextTick } from 'vue' const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)) /** * 串行挂载:每隔 stepMs 增加 1 个可见项,避免同时挂大量观察器/解码。 */ export function createSequentialMount() { let token = 0 const cancel = () => { token += 1 } /** * @param {{ total: number, stepMs?: number, settleMs?: number, setCount: (n: number) => void }} opts * @returns {Promise<{ cancelled: boolean }>} */ const run = async ({ total, stepMs = 220, settleMs = 300, setCount }) => { const t = ++token const n = Math.max(0, Number(total) || 0) setCount(0) await nextTick() if (t !== token) return { cancelled: true } if (!n) return { cancelled: false } for (let i = 0; i < n; i += 1) { if (t !== token) return { cancelled: true } await sleep(stepMs) if (t !== token) return { cancelled: true } setCount(i + 1) await nextTick() } if (t !== token) return { cancelled: true } if (settleMs > 0) { await sleep(settleMs) if (t !== token) return { cancelled: true } } return { cancelled: false } } return { run, cancel } }