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
74 lines
2.4 KiB
|
3 days ago
|
(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);
|