肉渣教程

H5 Web Workers

上一节 下一节

什么是Web Worker?

一个web worker就是一个跑在浏览器后台的JavaScript脚本程序;其不会阻塞网页页面的渲染,因为等于是跑在浏览器背后的另外一个进程。两个进程是相对独立的。

Web Worker非常适合高延迟的工作,也是进行并行运算的好工具。因为,它是运行在浏览器背后的独立进程

浏览器兼容性

下面列出的是各类型浏览器支持HTML Web Worker的最低版本。

API
Web Storage 4.0 10.0 3.5 4.0 11.5

检查是否支持Web Worker

虽然说不兼容web worker的浏览器都可以去自断经脉了,但出于对极致的追求,在使用web worker前最好还是用代码检测一下浏览器是否支持web worker;具体检测如下代码所示:

if (typeof(Worker) !== "undefined") {
    // 浏览器支持web worker
    // 可以干正事了
} else {
    // 小贼,你的浏览器太落后了,不兼容老夫的web worker呀
}

创建Web Worker本身的工作脚本

因为web worker是运行在浏览器背后独立的进程(js进程),所以需要提前准备好用来创建web worker进程的.js脚本文件:

var i = 0;

function timedCount() {
    i = i + 1;
    postMessage(i); // 把i的值传递给页面主进程
    setTimeout("timedCount()",500);
}

timedCount();

向页面主进程反馈信息:
如上例代码所示,postMessage()方法的作用就是让“web worker进程”向“HTML页面主进程”发送信息。而HTML页面主进程中的web worker对象则可以通过onmessage事件来获取postMessage发送过来的数据。

一般来说,web worker进程都会需要向页面主进程反馈信息的。

创建一个Web Worker对象

上面已经搞定好了一个web worker外部脚本,现在来看如何在页面主进程中来调用这个web worker工作脚本。(该web worker脚本被命名为“zhuanfou_workers.js”)

如下代码所示,这里做了一个检测,以保证不会重复新建web worker;其实同时创建多个web worker是没问题的,并行就是要多个worker一起干活,但是本例中,以示例为主,会保证只创建1个web worker。

if (typeof(w) == "undefined") {
    w = new Worker("./static/worker.js");
}

然后看一下该web worker对象是如何通过onmessage来接收web worker进程中postMessage方法发送过来的数据:

w.onmessage = function(event){
    document.getElementById("result").innerHTML = event.data;
};

当web worker进程发送数据过来时,onmessage方法内的代码就会运行,发送过来的数据会存在event.data内。


Web Worker的工作脚本的url地址必须与主进程页面保持在相同域名下;HTML页面可以引入放在任何第三方站点的js脚本,但是跨域的Web Worker工作脚本是无法被成功加载运行的。


停止一个Web Worker进程

当1个web worker进程在浏览器后台跑起来后,页面主程序就会不断监听其发送过来的信息;如果想要结束这个web worker进程来回收浏览器资源,则可以用terminate方法:

w.terminate();

释放Web Worker对象

上面例子页面主进程中的Web Worker对象就是变量w,如果想重复使用这个变量w,那就在结束该Web Worker进程后,把w变量重新赋值为空,即:

w = undefined;

完整的Web Worker案例

把上面的每一步联系起来,如下例所示:

<!DOCTYPE html>
<html>
<body>

<p>Web Worker进程发送过来的数据:<output id="result"></output></p>
<button onclick="startWorker()">创建 Worker</button> 
<button onclick="stopWorker()">终止 Worker</button>

<script>
var w;

function startWorker() {
    if(typeof(Worker) !== "undefined") {
        if(typeof(w) == "undefined") {
            w = new Worker("./static/worker.js");
        }
        w.onmessage = function(event) {
            document.getElementById("result").innerHTML = event.data;
        };
    } else {
        document.getElementById("result").innerHTML = "小贼,你的浏览器太落后了,不兼容老夫的web worker呀";
    }
}

function stopWorker() { 
    w.terminate();
    w = undefined;
}
</script>

</body>
</html>

运行一下


因为Web Worker是与页面主进程相对独立的进程,因此Web Worker这类外部运行的JS脚本进程是无法调用HTML页面的各种信息,诸如页面的各种HTML元素等。


H5 Web Workers

上一节 下一节