js如果同步运行一段非常耗时的代码 就会冻结用户与页面的交互 耗时越久 等待时间越长
例如有下面代码
for(let i = 66666,s=‘‘,ar=[];i--;) ar.push(‘<miku></miku>‘); document.body.innerHTML=ar.join(‘‘);
这段代码就有很多问题 其中知道拼接字符串已经算好的了 有些更糟糕的代码 直接N次innerHTML 都不想吐槽了!
现代浏览器都能跑动上面代码的 如果我把666666(5个6) 改为666666(你说几个6 考你眼力)估计都要跪
而且不光是元素数量多的问题 innerHTML还拿不到句柄 不方便接下来的操作。
------------------------------------------------
如何分块处理数据呢? 其实就是把原先的N个数据 分成一小块一小块 当处理到一定量的时候再放入一个新的队列中 最终完成后就可以callback回去 整个过程是异步的
如下 对数组删除重复元素的代码
<h3 id="hh3"></h3> <input type="button" value="async" id="btn1"></button> <input type="button" value="sync" id="btn2"></button>
const raf = function(t){ requestAnimationFrame(arguments.callee); hh3.innerHTML=t; }(); const fn1 = function(fn){ var i = 0; var l =ar.length; const f = Math.floor; const c = f(Math.sqrt(l)); const r = f(l/c); const part = l-c*r; const st = new Set(); const _ = ()=>{ while(++i<r){ for(let j = 0;j<c;++j)st.add(ar[i*c+j]); return setTimeout(_); } fn(st); }; _(); //var st = new Set();for(let i=ar.length*20;i--;) st.add(ar[i]||‘miku‘); //fn(st); }; const ar = Array.from({length:3e5},v=>(Math.random()*10).toFixed(1)); var fn2 = Function(‘ar‘,‘fn‘,function(s,fn1){ return (fn1+‘‘).replace(/\/{2,}(.+)/g,(a,b)=>s+=b),s; }(‘‘,fn1)); btn1.onclick = function(){ this.disabled = true; fn1((st)=>{ this.disabled = false; console.log([...st]); }) } btn2.onclick = function(){ this.disabled = true; fn2(ar,(st)=>{ this.disabled = false; console.log([...st]); }) }
点async 页面不会被阻塞住 只要等back结果就可以 但是你点sync明显会感觉整个页面顿了顿!
解释下代码
里面的去重算法O(n)复杂 是用的Set实现的 也可以用Map 低版本的的用hash可以实现基础的。
其中最关键的就是把需要分块的数据分解成了行列形式 内循环到达一定量时候开启新队列 。
这里行列并没有包括所有的数据 可能还有剩余的(可以再来个对剩余的遍历) 我就演示用的 请忽略。。
当处理的数据并不需要按顺序完成 而且数据量极大的时候 我们就应该用异步方式一块块处理 或者某些情况还可对ie10+开worker解决!
时间: 2024-10-25 14:42:20