js在web worker使用多线程

注:必须要在服务器环境。
什么是webworker?
Web Worker为Web应用程序提供了一种能在后台中运行的方法。通过Web Worker可以生成多个线程同时运行,并保证页面对用户的及时响应,完全不会影响用户的正常操作。
单线程:单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。简单的说就是处理事务的任务链,当只有一条链,所有的事情都在这一条链上执行时,那就是单线程。
优点:单线程较多线程来说,系统稳定、扩展性极强、软件丰富。
缺点:只有一个线程,代码顺序执行,容易出现代码阻塞(页面假死)。
多线程:有多条链时,那就是多线程了,当然并不是说多条线并行,而是说有一条主线程,处理整个程序任务的主方向的链,而其链上又有许许多多的分支,就像树枝那样,这样,既有了主线程去处理那些主要任务,又有了那些细小线程去处理耗时费力任务,从而让界面看起来更加流畅。
不容置疑的事实是:Javascript是单线程的,基于其特殊的用途,为了避免复杂性,从一开始,JavaScript就是单线程,这已经成了这门语言的核心特征,将来也不会改变。所以一定要明确这一点,同时也要理解对这个单线程的概念,理解不好就容易糊涂。JS的单线程是指一个浏览器进程中只有一个JS的执行线程,同一时刻内只会有一段代码在执行,但是浏览器有很多线程,是多线程的,当js线程在执行时,浏览器可以根据需求开相应的线程进行处理。
那能不能开启js的多线程?
可以,html5的webworker允许javascript多线程。
多线程是在原有主线程之外分了worker线程出来,但是子线程完全受主线程控制,且不得操作DOM。因为Worker线程不能直接访问和操作页面中的DOM属性,如果Worker线程需要访问页面中的某个DOM节点,必须通过postMessage API发消息给主线程,主线程在收到消息后获取页面中的某个DOM节点的属性,再通过postMessage的方式回传给Worker线程,这样就避免了冲突。
那么怎么使用webworker多线程呢?
首先说一下webworker使用的代码说明:
WEB主线程:
1.通过 worker = new Worker( url ) 加载一个JS文件来创建一个worker,同时返回一个worker实例。
2.通过worker.postMessage( data ) 方法来向worker发送数据。
3.绑定worker.onmessage方法来接收worker发送过来的数据。
4.可以使用 worker.terminate() 来终止一个worker的执行。
worker子线程:
1.通过postMessage( data ) 方法来向主线程发送数据。
2.绑定onmessage方法来接收主线程发送过来的数据。
注意:
1.子线程进行计算,不能进行 DOM BOM操作
2.子线程不能跨域,文件需放在同路径中
3.子线程不能套子线程
4.子线程 不和主线程共享数据,而是复制一份儿 哪怕是对象
2个demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>
    </style>
    <script>
function fn(n){ //写一个可以让程序假死的函数
    if(n<=2){
        return 1;  // 如果我们传进来的小于等于2 就走这个。
    }else{
        return fn(n-2)+fn(n-1);  //如果我们传进来的大于2,就一直自动的持续调用自己,直到小于2。这样可以让系统进入假死状态,需要处理很长时间才结束。
    }
}
        document.addEventListener('DOMContentLoaded',function(){
            var aBtn = document.querySelectorAll('input');
            var oW;//因为要做四个点击按钮,所以让线程为全局变量
            aBtn[0].onclick = function(){ //点击的时候 直接调用函数 让程序假死,然后点击第四个按钮,测试看看能不能弹1
                alert(fn(48));
            };
            aBtn[1].onclick = function(){ //点击的时候让子线程来执行这个 同样的函数,然后点击第四个按钮,测试看看能不能弹1
                oW = new Worker('fib.js');
                oW.postMessage(48);
                oW.onmessage = function(ev){alert(ev.data);};
            };
            aBtn[2].onclick = function(){ //测试成功后就用来终止子线程,,因为等待时间确实长。。你懂得
                oW.terminate();
            };
            aBtn[3].onclick = function(){  //作为测试函数。
                alert(1);
            };
        },false);
    </script>
</head>
<body>
<input type="button" value="开启主线程">
<input type="button" value="开启子线程">
<input type="button" value="关闭进程">
<input type="button" value="测试">
</body>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <input type="text" name="ipt" id="ipt" value="" />
        <button id="start">start</button>
        <button id="stop">stop</button>
        <button id="ale">alert</button>
        <script type="text/javascript">
            var ipt = document.getElementById("ipt");
            var stop = document.getElementById("stop");
            var start = document.getElementById("start");
            var ale = document.getElementById("ale");
            var worker = new Worker("js/test22.js");
            worker.onmessage = function(){
                ipt.value = event.data;
            };
            stop.addEventListener("click",function(){
                //用于关闭worker线程
                worker.terminate();
            });
            start.addEventListener("click",function(){
                //开起worker线程
                worker = new Worker("js/test22.js");
            });
            ale.addEventListener("click",function(){
                alert("i'm a dialog");
            });
        </script>
    </body>
</html>

test22.js

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

《参考:https://www.jianshu.com/p/3090eae158b7》
《参考:https://www.cnblogs.com/haodawang/articles/5850822.html》

猜你喜欢

转载自blog.csdn.net/qq_32447301/article/details/83583068