web worker

Web Workers 是 HTML5 提供的一个javascript多线程解决方案,我们可以将一些大计算量的代码交由web Worker运行而不冻结用户界面。在浏览器后台运行JavaScript, 而不占用浏览器自身线程。Web Worker可以提高应用的总体性能,并且提升用户体验。
学习自:
原文1
原文2

//test.html
<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>

    </head>
    <body>
        <script type="text/javascript">
            //WEB页主线程
            var worker =new Worker("worker.js"); //创建一个Worker对象并向它传递将在新线程中执行的脚本的URL
            worker.postMessage("hello world");     //向worker发送数据
            worker.onmessage =function(evt){     //接收worker传过来的数据函数
            console.log(evt.data);              //输出worker发送来的数据
            }
        </script>
    </body>
</html>

//worker.js
onmessage =function (evt){
  var d = evt.data;//通过evt.data获得发送来的数据
  console.log(evt)
  postMessage( d );//将获取到的数据发送会主线程
}
//在chrome中不可以运行

如果不用web worker:

document.querySelector('div').onclick = function() { 
    console.log('hello world'); 
  }; 

function fibonacci(n) { 
  return n < 2 ? n : arguments.callee(n - 1) + arguments.callee(n - 2); 
} 

 console.log(fibonacci(36)); 
//只有在等计算完成后才打印hello world

关于web worker的七件事

Web Worker 可以让你在后台运行Javascript

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <title>web worker fibonacci</title>

    </head>
    <body>
        <script type="text/javascript">
            onload =function(){
              var worker =new Worker('fibonacci.js');  
              worker.addEventListener('message', function(event) {
                var timer2 = (new Date()).valueOf();
                   console.log( '结果:'+event.data, '时间:'+ timer2, '用时:'+ ( timer2  - timer ) );
              }, false);
              var timer = (new Date()).valueOf();
              console.log('开始计算:40','时间:'+ timer );
              setTimeout(function(){
                  console.log('定时器函数在计算数列时执行了', '时间:'+ (new Date()).valueOf() );
              },1000);
              worker.postMessage(40);
              console.log('我在计算数列的时候执行了', '时间:'+ (new Date()).valueOf() );
            }  
        </script>
    </body>
</html>

//fibonacci.js
var fibonacci =function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
onmessage =function(event) {
    var n = parseInt(event.data, 10);
    postMessage(fibonacci(n));
};
//控制台:
开始计算:40 时间:1492829709415
我在计算数列的时候执行了 时间:1492829709419  
定时器函数在计算数列时执行了 时间:1492829710419  
结果:102334155 时间:1492829780583 用时:71168

限制:

  • Web Worker无法访问DOM节点;
  • Web Worker无法访问全局变量或是全局函数;
  • Web Worker无法调用alert()或者confirm之类的函数;
  • Web Worker无法访问window、document之类的浏览器全局变量;

不过Web Worker中的Javascript依然可以使用setTimeout(),setInterval()之类的函数,也可以使用XMLHttpRequest对象来做Ajax通信。

两种web worker

  1. 专用线程dedicated web worker
    只能被创建它的页面访问, 随当前页面的关闭而结束
//time.js
addEventListener('message',function(evt) {
    setTimeout(function(){
        console.log('finish')
        postMessage(200)
    },evt.data)
})
//time.html
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
    </head>
    <body>
    <button>click me</button>
    <script>
        var el = document.querySelector('button');
        el.addEventListener('click',function() {
            var worker = new Worker('time.js');
            worker.addEventListener('message',function(evt) {
                console.log('success')
            },false)
            setTimeout(function(){
                console.log('in')
            },1000)
            worker.postMessage(5000)
            console.log('begin')
        },false)
    </script>
    </body>
</html>
//控制台
begin 
in  
finish  
success
  1. 共享线程shared web worker
    为多个页面服务。在这种情况下,我们会创建一个共享线程的Shared web worker,它可以被与之相关联的多个页面访问,只有当所有关联的的页面都关闭的时候,该Shared web worker才会结束。
// shared_worker.js
function factorial(num){
    var i = 1,
        result = 1;
    for (; i <= num; i ++){
        result *= i;
    }
    return result;
}

var count  = 0;

self.addEventListener('connect', function(event){
    var port = event.ports[0]
    port.onmessage = function(event){
        var number = 0;
        count += 1;
        if (event.data){
           number = parseInt(event.data, 10) || 0;
           if (number > 0){
               number = factorial(number);
           }
        }
        port.postMessage("count " + count + ": " + number);
    };
    port.start();
});
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>using web worker</title>
</head>
<body>
    <script>
        function showMsg(msg){
            var p = document.createElement('p');
            p.innerHTML = msg;
            document.body.appendChild(p);
        }
        var worker = new SharedWorker('../js/shared_worker.js');
        worker.port.postMessage('60');
        worker.port.onmessage = function(event){
            showMsg(event.data);
        };
        worker.port.onerror = function(event){
            showMsg(event.message);
        }

        var worker1 = new SharedWorker('../js/shared_worker.js');
        worker1.port.postMessage('10');
        worker1.port.onmessage = function(event){
            showMsg("worker1: " + event.data); 
        };
        worker1.port.onerror = function(event){
            showMsg("worker1 " + event.message); 
        }
        worker1.onerror = function(event){
            showMsg("worker1 " + event.message); 
        }
        showMsg("shared worker start.");
    </script>
</body>
</html>

Web Worker使用XMLHttpRequest与服务端通信

通过Error事件捕捉错误信息

通过terminate()方法终止Web Worker

优点

  1. 可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信
  2. 可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()
  3. 可以使用XMLHttpRequest来发送请求
  4. 可以访问navigator的部分属性
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值