web worker和setTimeout的区别

本文比较了WebWorker与setTimeout在JavaScript中的执行特性,强调了WebWorker利用浏览器多线程提高效率,而setTimeout仅提供执行队列。通过实例说明了它们在性能和阻塞主线程上的区别,以及何时选择WebWorker处理耗时任务。
摘要由CSDN通过智能技术生成

从表面上看,web woker和setTimeout都不会阻塞js主线程,
两者最大的区别是web woker是真多线程,并且无法获取js主线程中的document以及其他会影响windowUI的函数例如alert()
setTimeout只是将要执行的内容压栈到队列最后执行,最终执行还是会到js主线程执行的,即运行环境最后还是主线程环境(可以获取document),此外一旦运行了某个setTimeout内容,如果里面的内容不存在其他的异步过程例如setTimeout,ajax,那么在运行这个代码过程会阻塞主线程
在单核电脑上,两者性能上讲几乎没区别,但是多核电脑上,web worker可以同时使用多个cpu执行内容效率自然更高
举个例子

let dom = document.getElementById("aa");
setTimeout(()=>{
  alert('2秒后1');
},2000);
setTimeout(()=>{
  for(var i=0;i<100000;i++){
	for(var j=0;j<100000;j++){
		for(var k=0;k<100000;k++){
			}
	}
	}
},1000);
setTimeout(()=>{
  alert('2秒后2');
},2000);
setTimeout(()=>{
  alert('2秒后3');
},2000);
console.log(dom);
setTimeout(()=>{
  for(var i=0;i<100000;i++){
	for(var j=0;j<100000;j++){
		for(var k=0;k<100000;k++){
			}
	}
	}
},2000);
console.log('end');
//以上先console出dom,然后输出'end'
//然后会执行3个alert,但是在执行栈中的3个alert并不一定是按续的,而且由于主线程要执行3个for循环而阻塞了
//执行3个alert的时间远大于2秒,也就是说,排队中的setTimeout必须等待主线程执行结束和第二个timeout执行阻塞结束才能执行
//一旦执行了最后一个耗时的alert代码,那么就会阻塞主线程
//以上全部代码最后用的都是js主线程,
let dom = document.getElementById("aa");
let w1=new Worker('./script1.js'); //script1内容是for循环1亿次结束后postMessage给主线程
let w2=new Worker('./script2.js'); //script1内容是for循环2亿次结束后postMessage给主线程
let w3=new Worker('./script3.js'); //script1内容是for循环5亿次结束后postMessage给主线程
w1.onmessage =function(){console.log(1)};
w2.onmessage =function(){console.log(2)};
w3.onmessage =function(){console.log(3)};
console.log(dom);
for(var i=0;i<10000;i++){ //for循环10000亿次
	for(var j=0;j<10000;j++){
		for(var k=0;k<10000;k++){
			}
	}
	}
console.log("end");
//以上代码会先输出dom,然后是end,最后分别是1,2,3
//因为3个web worker是利用浏览器的多线程能力执行的(就算是单核也是线程均衡分配执行时间的)
//3个web worker和主线程同时执行的,主线程先输出dom(因为定义worker之前没有阻塞的耗时操作)
//然后是3个woker根据操作耗时依次触发message事件但是需要等待主线程阻塞执行完毕,因为message时间也是在主线程中执行
//然后主线程for循环10000亿后才输出了end
//随后执行3个woker的onmessage输出1,2,3,此处是按序的,因为webworker中的执行触发其中的postMessage给主线程时,会将onmessage推入执行栈中,那么等主线程执行完毕后先入栈的先执行,

总结,setTimeout起始只是提供了执行队列,根据第二个时间参数进行队列排序然后执行,同样时间的排序并不一定是代码顺序
web woker则是真正使用了浏览器多线程能力
总结,任何情况下,不要在可能会在主线程执行的地方写耗时操作的代码,就算是在setTimeout里也一样,因为,一旦耗时操作的代码在主线程执行了,就会使得前端卡顿,复杂的处理逻辑完全应该被放入web worker中执行,执行完毕后的结果通知主线程.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值