关于web的多线程(Web Worker)

测试:有个查千万级的页面,查的特别慢导致页面都崩溃了,你们开发解决一下。
开发组:sql我们已经做优化了,它还是慢我们也没办法啊,优化我们都不会啊,新来的,要不你看一下?只要保证页面不崩就行。
我:嗯?好吧,刚来也没事干,就看一下吧。

关于sql优化学习尚浅,只知道降低查询结果集的数据量来解决,比如分库分表、建索引、分页查询,还有最近刚学习的Oracle强大的分区表!同事说保证页面不会崩溃就行了。。。呃,好的。

只考虑IE和谷歌浏览器,IE没有页面无响应时的处理机制,而谷歌会在页面很长时间无响应后,就会触发,弹出“页面已经崩溃了”的提示。

分析了一下页面崩溃的原因:

由于查询是同步的,会阻塞主线程,导致系统所有页面都处于“不可响应”的状态。
了解了原因后,可以采用多线程和异步的方式来解决:
1、改成异步查询
2、采取多线程查询(需要考虑线程相关问题,比如:死锁、线程安全等)
异步比出现很多不必要的问题。

异步不很简单么,ajax不就异步的么!
由于技术太古老以及专属框架,ajax无法应用上。。。网上说js的setTimeout函数就是异步的,然后我就将查询方法放到了该函数里,测试结果告诉我不行!!!

思考一下:异步和同步、阻塞和非阻塞,排列组合的4种情况。
(知识尚浅,有不正确的情指正)
感觉异步也是一个主线程,可能会阻塞,也可能不阻塞。像一个网页中的元素图片、文字之类,页面加载完成之后,图片才会慢慢的异步加载出来,且不会阻塞用户的响应操作。这和H5的标签特性好像有关系,img标签的src属性好像就是异步加载的。

异步好像行不通,那就研究多线程吧。

直接上代码,详细的用法讲解请参照Web Worker 使用教程

1、第一步创建子线程的commonWorker.js文件
//引入外部大佬封装好的查询组件js
importScripts('../common/EasyQueryVarxxx.js');

//监听主线程传来的参数
this.addEventListener('message',function(event){
	var sql=event.data;
	var resultMsg=easyQueryVerxxx(sql); //大佬封装的公共查询函数,传入sql语句,直接返回结果
	//把结果返回给主线程
	this.postMessage(resultMsg);
	console.log('worker query end');
	self.close();
},false);
2、在正常js文件中改变查询方式,通过commonWorker.js文件来查询结果
//开启子线程进行处理
var worker = new Worker("./commonWorker.js");
//向子线程传递参数
worker.postMessage("select xxx,xxx,xx, from t_xxxx");
//监听子线程发送回来的数据(回调函数)
worker.onmessage = function (event){
	var resultMsg=event.data;
	//已经在主线程中拿到结果了,然后正常处理就可以额
	console.log(resultMsg);
};

这是最简单的代码,要保证系统的可靠性,还需要做控制。假定子线程的查询需要2s的处理时间,由于后台发生了意外的情况,导致子线程2s后还没有返回,然后用户改变的查询条件又点击了一次,这时又一个线程去后台查询了,但这次没有意外,很快用户看到了结果,但由于上一个子线程正常返回了,用户就会看到结果后又被刷新为上一次的查询结果,或者其它未知的情况。

我负责的模块由于性能需要,根据查询条件来决定是否开启子线程去查询。

所以对代码稍作改造,加入一个共享变量来同步,就可以了。

加入共享变量
//定义一个全局的同步变量
var synchroFlag=0;

--------------
//每开启子线程去处理时
synchroFlag=1;
var worker = new Worker("./commonWorker.js");
worker.postMessage("select xxx,xxx,xx, from t_xxxx");
worker.onmessage = function (event){
	var resultMsg=event.data;
	console.log(resultMsg);
	//释放
	synchroFlag=1;
};
--------------

//在查询中添加判断
	if(synchroFlag>0){
		alert("请稍等上一次查询结束后,再查询。");
		return false;
	}

这样,就可以基本满足业务需要了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值