const myWorker = new Worker(jsUrl, options);
1 | // 主线程 |
2 | var myWorker = new Worker(‘worker.js’, { name : ‘myWorker’ }); |
3 | // Worker 线程 |
4 | self.name // myWorker |
Worker()
构造函数返回一个 Worker 线程对象,用来供主线程操作 Worker。Worker 线程对象的属性和方法如下:
1 | worker.onerror(function (event) { |
2 | console.log([ |
3 | 'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message |
4 | ].join('')); |
5 | }); |
1 | worker.onmessage = function (event) { |
2 | console.log(‘Received message ‘ + event.data); |
3 | doSomething(); |
4 | } |
1 | worker.postMessage(‘Hello World’); |
2 | worker.postMessage({method: ‘echo’, args: [‘Work’]}); |
Web Worker 有自己的全局对象,不是主线程的window,而是一个专门为 Worker 定制的全局对象。因此定义在window上面的对象和方法不是全部都可以使用。
Worker 线程有一些自己的全局属性和方法:
1 | self.onmessage = function (/e/) { |
2 | self.postMessage(‘You said: ‘ + e.data); |
3 | }; |
Web Worker的作用就是为javascript提供多线程环境,允许主进程将一些任务交给Worker在后台进行。这样的话,在一些计算密集型或者高延迟任务执行的时候就不会影响到主进程的执行,提高流畅度。
Worker一旦执行成功,就会一直运行,比较耗费资源。所以一旦只要使用完毕,就应该关闭。
主线程与 Worker 之间的通信内容,可以是文本或者对象,也可以交换二进制数据,比如 File、Blob、ArrayBuffer 等类型。
需要注意的是,这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。但是,拷贝方式发送二进制数据,会造成性能问题。为了解决这个问题,JavaScript 允许主线程把二进制数据直接转移给子线程,但是一旦转移,主线程就无法再使用这些二进制数据了,这是为了防止出现多个线程同时修改数据的麻烦局面。这种转移数据的方法,叫做 Transferable Objects 。这使得主线程可以快速把数据交给 Worker,对于影像处理、声音处理、3D 运算等就非常方便了,不会产生性能负担。
下面是一个例子。
1 | // Transferable Objects 格式 |
2 | worker.postMessage(arrayBuffer, [arrayBuffer]); |
3 | // 例子 |
4 | var ab = new ArrayBuffer(1); |
5 | worker.postMessage(ab, [ab]); |
参考文献
Web Worker 使用教程 - 阮一峰的网络日志
使用 Web Workers - Web API 接口参考 | MDN