示例:点击按钮,往页面插入100000个div元素
const btn = document.querySelector('#add');
const datas = new Array(100000).fill(0).map((_, i) => i);
btn.onclick = () => {
// 具体的执行操作
const _consumer = (item, i) => {
const div = document.createElement('div');
div.textContent = i;
document.body.appendChild(div);
}
// 时间间隔的判断,可不传;默认为requestIdleCallback
const _chunkSplitor = (task) => {
setTimeout(() => {
task((time) => time < 16)
}, 20);
}
// 分时函数
performChunk(datas, _consumer, _chunkSplitor);
function performChunk(datas, consumer, chunkSplitor) {
// 参数归一化,即可直接传1000或数组[1,2,3,4....]
if (typeof datas === 'number') {
datas = new Array(datas);
}
if (datas.length === 0) {
return;
}
// 兼容有window.requestIdleCallback的浏览器
// 此处使用了globalThis是因为node环境没有window
if(!chunkSplitor && globalThis.requestIdleCallback){
chunkSplitor = (task)=>{
requestIdleCallback((idle)=>{
debugger
task(()=>idle.timeRemaining()>0)
})
}
}
let i = 0;//任务下标
// 具体的执行函数方法
function _run() {
if (i === datas.length) {
return;
}
chunkSplitor((hasTime) => {
const now = Date.now();
while (hasTime(Date.now() - now) && i < datas.length) {
//这一帧还有空闲时间
const item = datas[i];
consumer(item, i);
i++;
}
_run();
})
}
_run();
}
}