You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
2.4 KiB

(function (global) {
'use strict';
var DEFAULT_BUDGET_MS = 2;
/**
* 空闲切片调度:单次回调预算默认 2ms,可跨帧续跑。
* @param {function(function():boolean):void} work 入参 isExpired(),返回 false 表示还有剩余工作
* @param {number=} budgetMs
*/
function runIdle(work, budgetMs) {
var budget = budgetMs > 0 ? budgetMs : DEFAULT_BUDGET_MS;
var schedule = function (fn) {
if (typeof global.requestIdleCallback === 'function') {
global.requestIdleCallback(fn, { timeout: 200 });
} else {
global.setTimeout(fn, 0);
}
};
var step = function () {
var start = performance.now();
var expired = function () {
return performance.now() - start >= budget;
};
var more = true;
try {
work(expired);
// work 约定:若需续跑,在内部检测 expired 后自行再次 schedule;此处兼容返回值
} catch (e) {
console.warn('[调试工作台] idle 任务失败', e);
more = false;
}
return more;
};
// 简化:提供 runChunks 辅助
schedule(function () { 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) {
if (typeof global.requestIdleCallback === 'function') {
global.requestIdleCallback(tick, { timeout: 200 });
} else {
global.setTimeout(tick, 0);
}
} else if (onDone) {
onDone();
}
};
tick();
}
global.PWIdle = {
budgetMs: DEFAULT_BUDGET_MS,
run: runIdle,
forEachChunk: forEachChunk,
};
})(window);