由于JavaScript单线程的特性,在执行CPU密集型任务时(如大数组排序)会阻塞网页的渲染,解决办法一般是使用setTimeout函数对任务进行分割,或者把这类任务交由 web worker 处理。今天遇到一个对大数组排序的问题,需要使用任务分割来避免阻塞,在这里记录下我的实现方法。在实现时我将 while 语句进行了分割,避免出现大循环体语句一直进行计算,主要代码如下:
// 将 while 控制语句进行分割
// expression 相当于 while 的条件判断
// statement 相当于 while 循环体语句
async function while_async(expression, statement){
while(expression()){
await while_seg(expression, statement);
}
}
let while_seg = (expression, statement) => new Promise((resolve, reject) => {
setTimeout(()=>{
let i = 0;
let while_size = 50000;
while(expression()){
i++;
statement();
// 如果 while 内循环次数大于 while_size ,则进入事件循环
if(i>while_size)break;
}
resolve();
}, 0);
});
应用在大数组排序上,效果对比可以在这里查看:https://codepen.io/liuyaqi/pen/dmZdPe
height="351" width="650" scrolling="no" title="while_seg" src="//codepen.io/liuyaqi/embed/dmZdPe/?height=351&theme-id=0&default-tab=result&embed-version=2" allowfullscreen="true">See the Pen <a href="https: