JS中如何使用多线程
介绍
Worker可以为JavaScript创建多线程,且Worker 是运行在后台的
JavaScript,独立于其他脚本,不会影响页面的性能。主线程在运行的时候,worker也在后台运行,两者互不干扰,当worker线程完成任务后就可以将结果返回给主线。
当创建一个新的worker时,该代码会运行在一个全新的javascript的环境中,是完全和原JS隔离,这时我们把原JS(创建新worker的)脚本叫做主线程,而被创建的新的worker叫做子线程
浏览器的支持程度
除了 Internet Explorer外,其他主流浏览器均支持 Web Worker。
Worker的使用
1. 创建Worker对象
var worker=new Worker("xxx.js"); //xxx.js是子线程所执行的js文件
2. 传入参数
worker.postMessage(参数);
3. 获取返回的参数
worker.addEventListener('message', function (e) {
console.log('message ', e.data);
});
4. 异常处理
worker.onerror = function (err) {
}
5. 终止线程(过多的开启worker线程非常浪费资源所以在使用过后可以终止它)
worker.terminate();
6. 执行的子线程中接收参数
self.onmessage = function(event) {
console.log("onmessage:",event.data);
};
7. 执行的子线程向主线程传值
postMessage(子线程中的值);
8. 子线程中终止
self.close();
示例
场景
js通过http请求客户端本地的服务(实现读卡功能)
1. 主线程js
var jzk_worker=new Worker("Web_1920/js/child_thread/jzk.js");
jzk_worker.postMessage("in");
//接收消息
jzk_worker.addEventListener('message', function (e) {
console.log('就诊卡信息: ', e.data);
var cardNo= e.data.retBody.Track2;
if(cardNo.length>1){
checkNumCommit(cardNo);
}else{
console.log("******卡片不合法*******");
$("#div_text_dialog").show().delay(1800).hide(100);
$("#text_dialog").text("插入卡片不合法,请检查卡片是否插反");
}
});
2. Web_1920/js/child_thread/jzk.js中的内容
var f; //标识读卡退卡
//获取主线程传入的值
self.onmessage = function(event) {
console.log("onmessage-jzk:",event.data);
f=event.data;
read(f);
};
/**
* 就诊卡相关
*/
var CZD_JZK = CZD_JZK || {},
TOOL_MAIN_dataTj = TOOL_MAIN_dataTj || {};
CZD_JZK.responseAjax = function(datajson) {
var strurl= "http://127.0.0.1:7810";
var request = new XMLHttpRequest();
console.log("request:"+JSON.stringify(request));
request.onload = function(){
console.log("------"+request.responseText);
var rd=JSON.parse(request.responseText);
console.log("funcName"+datajson.funcName);
if(datajson.funcName =="ReadMSCardAsyn" && rd.retBody!=""){
console.log("---读取到卡信息---"+JSON.stringify(rd.retBody));
postMessage(rd);
}
}
request.open("post",strurl);
request.send(JSON.stringify(datajson));
}
/**
* 打开读卡器
*/
CZD_JZK.OpenCardReader = function(){
TOOL_MAIN_dataTj.funcName = "OpenCardReader";
CZD_JZK.responseAjax(TOOL_MAIN_dataTj);
}
/**
* 读就诊卡
*/
CZD_JZK.ReadMSCardAsyn = function(readTime){
if (readTime == null || readTime == "") {
readTime = "30";
}
TOOL_MAIN_dataTj.funcPara = readTime.toString();
TOOL_MAIN_dataTj.funcName = "ReadMSCardAsyn";
CZD_JZK.responseAjax(TOOL_MAIN_dataTj);
}
/**
* 关闭读卡器
*/
CZD_JZK.CloseCardReader = function(){
TOOL_MAIN_dataTj.funcName = "CloseCardReader";
CZD_JZK.responseAjax(TOOL_MAIN_dataTj);
}
//进卡并读卡
function inCard(){
console.log("------------调用读卡器----------------");
CZD_JZK.OpenCardReader();// 打开读卡器
CZD_JZK.ReadMSCardAsyn(1);
setInterval(function(){
CZD_JZK.ReadMSCardAsyn(1);
},1500);
}
function read(f){
console.log("f:",f);
if("out"==f){
CZD_JZK.CloseCardReader();
}else if("in"==f){
inCard();
}
}