JS实现多线程Worker

js是单线程的:javascript作为脚本语言,主要与用户交互,以及Dom操作,这就决定了js只能是单线程,否则会带来很复杂的同步问题。

  1. h5提供js分线程 web workers:可以将一些计算量大的代码交由web worker运行而不冻结用户界面。
  2. Worker API

worker构造函数,加载分栈执行的js文件

worker.prototype.onmessage:用于接收另外一个线程的回调函数

worker.prototype.postMessage向另外一个函数发送消息

     3.缺点  :

但是worker代码不能直接操作dom,不能跨域加载js,不是每个浏览器都支持这个新特性,可以不阻塞主线程

使用:创建在分线程执行js文件,在主线程js中发送消息并设置回调

例子:在html页面中,让分线程计算斐波拉数列,然后返回数据

<body>
     <input type="text" placeholder="数值" id="num">
     <button id="btn">计算</button>
</body>
<script>
        var input = document.getElementById('num');
        var btn = document.getElementById('btn');
        btn.onclick = function(){
            var number = input.value;
            // 创建一个worker对象
            var worker = new Worker("worker.js");
            // 向分线程发送消息
            worker.postMessage(number);
            console.log('主线程向分线程发送数据')
            // 绑定接收消息
            worker.onmessage = function(event){
                console.log("主线程接收分线程返回的数据");
                alert(event.data);
                // event.data 就是返回的数据
            }
        }
</script>

worker通过new方式创建出来,并且写入分线程的途径,这里采用相对路径,同于目录下的worker文件

worker.js文件  

var onmessage = function(event){
    // event.data就是接受的数据
    // 不能函数声明
    var number = event.data;
    console.log('分线程接收到主线程的数据'+number);
    // 计算
    var result = fibonacci(number);
    postMessage(result);
    console.log("分线程向主线程传递数据");
    console.log(this);
    // 全局对象就不是window了
    // 并且此页面根本就不可访问window对象
    // 分线程中的全局对象不再是window,所以在分线程中不可能再更新界面
function fibonacci(n){
    return n<=2 ? 1:fibonacci(n-1)+fibonacci(n-2);
    // 递归调用函数内部调用自己
} 
}

worker文件返回数据的时候也采用postMessage的方法,但是在这个this并不是在html中window对象,所以操作不了界面。

扫描二维码关注公众号,回复: 14916056 查看本文章

这样因为计算结果可能比较久,因为js单线程,所以此时前端页面交互阻塞,如果交给worker去处理,虽然数据返回结果较慢,但是用户可以继续操作界面。

猜你喜欢

转载自blog.csdn.net/weixiwo/article/details/129497655