Web Worker

Web Workers 使得一个Web应用程序可以在与主执行线程分离的后台线程中运行一个脚本操作。这样做的好处是可以在一个单独的线程中执行费时的处理任务,从而允许主(通常是UI)线程运行而不被阻塞/放慢。

前言

我们知道JS在执行的时候是单线程的。也就是在同一时间只能处理一件事。单线程的程序在执行的时候后面的代码是不会执行的。这样的设计一开始是为了防止两个不同的方法同时对一个Dom进行修改,则这样就会造成页面显示元素出现问题。

HTML5则提出了Web Worker的标准,JS中可以允许有多个线程。其子线程完全受主线程控制,且子线程不能操纵Dom。

创建Web Worker

首先要说的是Worker() 是一个构造函数,通过

1
var worker = new Worker('worker.js');

其中的Worker('worker.js')就是从一个单独的JS创建一个子线程。

Web Worker的基本原理就是在当前的主线程中加载一个只读的文件来创建一个新的线程。两个线程同时存在,互不阻塞。

销毁线程的方法有两种
方法一:在主线程中调用terminate();

1
2
3
4
// main.js
var worker = new Worker('worker.js');

worker.terminate();

方法二:在子线程中调用close();

1
2
3
// worker.js

self.close()

线程通讯

在Web Worker中提供了postMessageonmessage来发送/接受数据。

1
2
3
4
5
6
var worker = new Worker('worker.js');

worker.postMessage("i am data from main");
worker.onmessage = function(e) {
console.log(e.data); // i am data from worker.js!
}
1
2
3
4
5
6
// worker.js

onMessage = function (e) {
console.log(e.data); // i am data from main
postMessage('i am data from worker.js!')
}

要注意的是子线程不与主线程共享数据而是复制,即使是引用类型的数据!

共享线程

共享线程的设计是为了防止线程重复的创建与销毁。

1
var worker = new SharedWorker('sharedworker.js');

共享线程也同样的使用postMessage传递数据,只是调用的方式略有不同。

1
worker.port.postMessage("test sendMessage");

Worker作用域

在创建Web Worker的时候独立的JS文件会运行在一个全新的JS环境中(WorkerGlobalScope),该环境与主线程的环境完全隔离。

WorkerGlobalScope是worker的全局对象,同样的和主线程的window一样包含一些基本的方法。在子线程中同样的可以发送http请求。然后将获取的数据交给主线程使用。

hi you can see me