(function (global) { 'use strict'; var DEFAULT_BUDGET_MS = 2; function scheduleIdle(fn) { if (typeof global.requestIdleCallback === 'function') { global.requestIdleCallback(fn, { timeout: 200 }); } else { global.setTimeout(fn, 0); } } /** * 空闲切片调度:单次回调预算默认 2ms,可跨帧续跑。 * @param {function(function():boolean):boolean|void} work * 入参 isExpired();返回 false 表示还有剩余工作,应继续调度。 * @param {number=} budgetMs */ function runIdle(work, budgetMs) { var budget = budgetMs > 0 ? budgetMs : DEFAULT_BUDGET_MS; var step = function () { var start = performance.now(); var expired = function () { return performance.now() - start >= budget; }; var more = true; try { more = work(expired) !== false; } catch (e) { console.warn('[调试工作台] idle 任务失败', e); more = false; } if (more === false) scheduleIdle(step); }; scheduleIdle(step); } /** * 分片遍历数组。 * @param {Array} list * @param {function(*,number):void} visit * @param {function():void=} onDone * @param {number=} budgetMs */ function forEachChunk(list, visit, onDone, budgetMs) { var i = 0; var budget = budgetMs > 0 ? budgetMs : DEFAULT_BUDGET_MS; var tick = function () { var start = performance.now(); while (i < list.length && performance.now() - start < budget) { visit(list[i], i); i += 1; } if (i < list.length) { scheduleIdle(tick); } else if (onDone) { onDone(); } }; tick(); } global.PWIdle = { budgetMs: DEFAULT_BUDGET_MS, run: runIdle, forEachChunk: forEachChunk, schedule: scheduleIdle, }; })(window);