使用Web Worker线程后台加载数据

使用Web Worker线程后台加载数据

【引言】

JavaScript 其中有一个的特性是单线程,这个特性往往在我们进行大量运算或者操作的时候,我们不能做其他的事件。这种情况我们通常会说,卧x,我卡住了。

那么为什么 JavaScript 不设计成多线程呢?主要是由于它被设计之初就是作为浏览器脚本语言,主要用途是与用户互动,以及操作 DOM 树。如果设计成多进程将会带来非常复杂的同步问题,将给开发人员带来巨大的工作量和难题。

由于单线程在前端始终是个痛点,不能很好的利用我们的 CPU 的计算能力,所以 HTML5 提出了 Web Worker 标准,允许 JavaScript 脚本创建多个线程 ,但同时他们也为了安全考虑,将创建的子线程完全由主线程控制,而且不能操作 DOM 树。

由于我的项目需要使用到多线程来进行一些及时的检查或者改变内容,最开始我尝试使用简单的 setTimeOut 或者 setInterval 来进行一些操作,但是我发现有时候总会出一些意料之外的 BUG ,所以我为此不得不寻找一个良好的方案,最终我找到和学习了 Web Worker 解决了此类问题。下面是我的一些代码。

【代码】

JavaScript部分代码

//创建一个新的worker线程
const worker = new Worker('../../../Controller/Private/Home/AdminView/worker.js');

//异步获取全部同事
function asyncGetAllColleagueData(){
    worker.onmessage = e => {
        const result = e.data; 
        //{"info":[{"at":"2020033007","ne":"小红","av":"5","le":"2","ss":"0","dt":"2020-03-30 17:31:56","ph":"18160114163"}]}
        
        var dataJson = result['info']; 
        if(result['fg'] == 0){
            plus.nativeUI.toast("异常登录,请联网重试");
            return false; //异常
        }
        //新同事默认为0
        var newColleagueCount = 0;
        var newColleagueHTML = "";
        for (var n in dataJson) {
            if(dataJson[n].ss == 0){ //有新同事的申请
                newColleagueCount ++;//新同事申请数量
                newColleagueHTML += '<article>'+
                                        '<img src="http://123.56.107.97/picture/'+dataJson[n].av+'.png" />'+
                                        '<div><p>'+dataJson[n].ne+'</p>'+
                                        '<p>'+dataJson[n].ph+'</p>'+
                                        '<p>'+dataJson[n].at+'</p></div>'+
                                        '<span>操作</span>'+
                                    '</article>';
            }  
        }
        if(newColleagueCount !== 0){//如果新同事申请不为0的话
            document.getElementById("contentNewColleagueTips").innerText = newColleagueCount;
            document.getElementById("setStyle_contentNewColleaguePage").innerHTML = newColleagueHTML;
            document.getElementById("contentNewColleagueTips").style.display = "block";
        }else{
            document.getElementById("contentNewColleagueTips").style.display = "none";
        } 
    }; 
    //提交到后台的线程进行处理
    var accountValue = localStorage.getItem("at");
    var status = 1;
    worker.postMessage(['asyncGetAllColleagueData',accountValue,status]);
}
asyncGetAllColleagueData();
onmessage = e => {
	const message = e.data;
	if(message[0] == "asyncGetAllColleagueData") {
		//检查状态是否为1,为1则开启循环执行
		if(message[2] !== 1 ){
			return false;
		}
		fetch('http://www.artisancode.cn/jxAdminGetAllColleagueData', {
			headers: {
				'Content-Type': 'application/json'
			},
			mode: 'cors',
			method: 'POST',
			body: JSON.stringify({
				"accountValue" :message[1]
			}),
		}).then(function(response){
			return response.text();
		}).then(function(text){
			
			returnArray =  JSON.parse(text);
			postMessage(returnArray);
			
		});
	}
};

Laravel部分代码

public function AdminGetAllColleagueData(Request $request){

    $contentType = isset($_SERVER["CONTENT_TYPE"]) ? trim($_SERVER["CONTENT_TYPE"]) : '';
    //判断传递的类型
    if ($contentType != "application/json") {
        $returnArray = array('fg' => 0 );//异常
        return json_encode($returnArray,JSON_UNESCAPED_UNICODE);
    }

    $accountValue = $request -> json('accountValue');
    //检查传递的数据是否为空
    if($accountValue == ""){
        $returnArray = array('fg' => 0 );//异常
        return json_encode($returnArray,JSON_UNESCAPED_UNICODE);
    }

    $friendAccount = "f".$accountValue;
    //查询自己的朋友
    $myFriendInfo = DB::connection('r_fd')->table($friendAccount)->get();
    DB::disconnect('r_fd');
    if($myFriendInfo ->isEmpty()){
        $returnArray = array('fg' => 0 );//异常
        return json_encode($returnArray,JSON_UNESCAPED_UNICODE);
    }else{
        //查询朋友的头像和姓名
        $myFriendInfoTable = 'b'.$myFriendInfo[0] ->at;
        $result = DB::table("r_fd.{$friendAccount}")
            ->join("r_ba.{$myFriendInfoTable}","r_ba.{$myFriendInfoTable}.at",'=',"r_fd.{$friendAccount}.at")
            ->join("r_lg.ql","r_lg.ql.at",'=',"r_fd.{$friendAccount}.at")
            ->get();
        $returnArray = ['info' => $result];
        return json_encode($returnArray,JSON_UNESCAPED_UNICODE);
    }
}


回复列表



回复操作

正在加载验证码......

请先拖动验证码到相应位置

发布时间:2020-03-30 12:14:41

修改时间:2020-03-31 21:43:21

查看次数:78

评论次数:0