Worker

worker

JavaScript 是一门基于单线程异步操作的语言, 这是为了避免多线程带来的复杂性.
对于一些好事的网络请求, 在 JS 中一般都使用异步执行来避免阻塞.
但是, JS 中也是可以开启其他线程的, 也就是 worker. 可以说这就是 JS 中的多线程.
worker 虽然可以开启主线程以外的线程执行一些其他操作, 但是它和主线程还是有区别的. 应该理解为辅助线程

与主线程的区别

1. 上下文对象不同

通俗讲就是 this 指向不同, 主线程的 this 执行 window 对象(函数内 this 另当别论), 而 worker 线程 this 指向一个 DedicateWorkerGlobalScope 对象. 在 worker 线程中无法使用 window 对象, 在 worker 线程访问 window 会报 window is not defined 异常, 但是仍然可以使用 window 下的许多对象和函数.

2. 无法操作 DOM 元素

在 worker 线程中无法去操作页面的元素, 因为多个线程同时操作 dom 可能导致页面错误, 而且会使程序变得复杂, 所以在 JS 中, 限制了主线程以外的线程操作 dom 元素

创建线程

创建 worker 使用 window 对象的 Worker 构造函数, Worker 接受一个 JS 文件的 URL 作为参数, 该 JS 文件代码将在 worker 线程中执行

main.js

var worker = new Worker('./worker');

worker.js

console.log('worker start');
setInterval(function() {
  console.log('worker working');
}, 10000);

终止线程

终止线程可以在 main.js 中调用 worker 对象的 terminate 函数, 也可以在 worker 线程(worker.js)中调用 worker 上下文对象的 close 函数

terminate

main.js

var worker = new Worker('./worker');
// 5秒后终止线程
setTimeout(function() {
  worker.terminate();
}, 5000);

worker.js

console.log('worker start');
setInterval(function() {
  console.log('worker working');
}, 10000);

close

var worker = new Worker('./worker');

worker.js

console.log('worker start');
setInterval(function() {
  console.log('worker working');
}, 1);
// 5秒后终止线程
setTimeout(function( {
  close();
}))

线程通信

线程通信时通过 postMessage 函数发送数据, 通过 onmessage 事件监听数据. postMessage 接受一个参数, 这个参数会传递个指定的对应的线程, 对应线程的 onmessage 事件的处理函数接收一个参数 event, event.data 为 postMessage 函数发送的数据. 需要注意的是, 线程间通信的数据是不共享的, 通过 postMessage 发送的数据会被克隆, 生成一个副本. 数据的克隆使用结构化克隆算法(不同浏览器可能实现方式不一样), 所以有些数据无法拷贝, 例如函数. 当传入的数据包含无法克隆的数据类型是, 会抛出一个错误.

main.js

var worker = new Worker('./worker.js');
// 监听 worker.js 中的 postMessage
worker.onmessage = function(event) {
  console.log(event.data);
}
// 向 worker 发送一个消息
worker.postMessage('message from main.js');

worker.js

// 接收发送给这个线程的数据
onmessage = function(event) {
  console.log(event.data);
  // 接收的数据后发送一个 copy 消息
  postMessage('message from worker.js');
}

错误处理

当 worker 线程跑出错误时, 会触发 onerror 事件, 可以使用 worker.onerror 事件处理 worker 线程的错误

main.js

var worker = new Worker('./worker');
worker.onerror = function(error) {
  console.log('worker throw error: ', error);
}

worker.js

throw new Error('worker throw error');
close();

引入脚本

JS 中用 import 引入其他 JS 代码或其他文件, 在 worker 线程中引入其他 JS 代码使用 importScript 函数. importScript 函数可接收 0 个或多个 JS 文件 URL 作为参数.

worker.js

importScript('./log.js');
log('import script');

log.js

function log(message) {
  console.log(message);
}

未完待续…

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值