js多线程的实现-Worker

你们都知道js是基于单线程的,而这个线程就是浏览器的js引擎。
首先来看一下你们用的浏览器都具备那些线程吧。javascript

若是咱们要执行一些耗时的操做,好比加载一张很大的图片,咱们可能须要一个进度条来让用户进行等待,在等待的过程当中,整个js线程会被阻塞,后面的代码不能正常运行,这可能大大的下降用户体验,这时候咱们就指望拥有一个工做线程来处理这些耗时的操做。在传统的html时代是基本不可能实现的,而如今,咱们拥有一种叫作worker的东西。它是js里的一个类,而咱们只须要建立它的实例就可使用它。html

var worker = new Worker(js_file_path);

参数填上你的js文件的路径,这个js文件将会在浏览器新开的线程里运行,而与原先的js引擎的线程并不影响。java

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>worker</title>
</head>
<body>
    <input type="text" name="ipt" id="ipt" value=""><br>
    <input type="button" name="start" id="start" value="start">
    <input type="button" name="stop" id="stop" value="stop">
    <input type="button" name="alert" id="alert" value="alert">
    <script type="text/javascript">
        var ipt = document.getElementById("ipt");
        var start = document.getElementById("start");
        var stop = document.getElementById("stop");
        var alt = document.getElementById("alert");
        var worker = new Worker("js/test.js");
        function getMessage() {
            worker.onmessage = function() {
                ipt.value = event.data;
            }
        }
        getMessage();
        stop.addEventListener("click", function() {
            //用于关闭worker线程
            worker.terminate();
        })
        start.addEventListener("click", function() {
            //开启worker线程
            worker = new Worker("js/test.js");
            getMessage();
        })
        alt.addEventListener("click", function() {
            alert("i'm a dialog");
        })
    </script>
</body>
</html>

 

test.js里的代码,也就是存在于worker线程里的代码web

var i = 0;
function mainFunc(){
    i++;
    //把i发送到浏览器的js引擎线程里
    postMessage(i);
}
var id = setInterval(mainFunc,1000);

运行起来咱们会发现chrome

点击"alert"里的“肯定”后,它的数值并不是2,而是一个比2更大的数浏览器

虽然dialog的弹出会阻塞js引擎线程,可是并不影响worker线程的运行,因此,在咱们点击肯定后,只是在js引擎线程上更新了新的内容,而数值是一直在跑动的,这就说明worker线程和本来的js线程互不影响.服务器

那么既然互不影响,两个线程之间要怎么来联系呢,答案其实已经在代码里了,那就是onPostMessage 和 onmessage这两个函数,其中onPostMessage(data)的参数是你要传递的数据,而onmessage是一个回调函数,只有在接受到数据时,onmessage会被回调,onmessage有一个隐藏的参数,那就是event,咱们能够用event.data获取到传递过来的数据来更新主线程。函数

使用worker线程应注意的是,全部js里集成的对象都在js线程里,而并不是worker线程。
例如咱们在worker线程里写上:post

var a = document.getElementById("a");

结果你会获得一条Error,告诉你找不到document,或者document is undefined。因此咱们尽可能把须要的东西都写到主线程里,而只把耗时的操做写到worker线程里。spa

注意:若是所运行的html页面在本地启动脚本,chrome会报错。

缘由分析:Chrome从本地文件运行脚本时不容许加载web worker.

解决办法:启动web容器,经过服务器访问页面资源。好比:localhost:8081/worker.html 或这换种浏览器试试。

 

参考: https://www.cnblogs.com/haodawang/articles/5850822.html

相关文章
相关标签/搜索