web worker

WebWorker是JavaScript实现多线程的一种机制,它允许在后台线程执行耗时任务,避免阻塞主线程。worker线程与主线程通过postMessage通信,有专用worker和共享worker两种类型,但受到同源、文件、DOM操作、通信和脚本等限制。使用时需注意资源管理和错误处理。
摘要由CSDN通过智能技术生成

什么是web worker

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

它的作用就是给JS创造多线程运行环境,允许主线程创建worker线程,分配任务给后者,主线程运行的同时worker线程也在运行,相互不干扰,在worker线程运行结束后把结果返回给主线程。这样做的好处是主线程可以把计算密集型或高延迟的任务交给worker线程执行,这样主线程就会变得轻松,不会被阻塞或拖慢。这并不意味着JS语言本身支持了多线程能力,而是浏览器作为宿主环境提供了JS一个多线程运行的环境。

不过因为worker一旦新建,就会一直运行,不会被主线程的活动打断,这样有利于随时响应主线程的通性,但是也会造成资源的浪费,所以不应过度使用,用完注意关闭。或者说:如果worker无实例引用,该worker空闲后立即会被关闭;如果worker实列引用不为0,该worker空闲也不会被关闭。

种类

web worker有两类:
一.专用worker
是指标准worker仅在单一脚本且,仅仅能被首次生成它的脚本使用

二.共享worker

可以同时被多个脚本使用。

使用限制

1、同源限制
worker线程执行的脚本文件必须和主线程的脚本文件同源,这是当然的了,总不能允许worker线程到别人电脑上到处读文件吧
2、文件限制
为了安全,worker线程无法读取本地文件,它所加载的脚本必须来自网络,且需要与主线程的脚本同源
3、DOM操作限制
worker线程在与主线程的window不同的另一个全局上下文中运行,其中无法读取主线程所在网页的DOM对象,也不能获取 document、window等对象,但是可以获取navigator、location(只读)、XMLHttpRequest、setTimeout族等浏览器API。
4、通信限制
worker线程与主线程不在同一个上下文,不能直接通信,需要通过postMessage方法来通信。这个过程中数据不是被共享,而是被复制
5、脚本限制
worker线程不能执行alert、confirm,但可以使用 XMLHttpRequest 对象发出ajax请求。

使用

1.生成webWorker
MDN

// 主线程

调用Worker() 的构造器,指定一个脚本的URI来执行worker线程(main.js):
var myWorker = new Worker('worker.js', { name : 'myWorker' });

// Worker 线程
self.name // myWorker

第一个参数是脚本的网址(必须遵守同源政策),该参数是必需的,且只能加载 JS
脚本,否则报错。第二个参数是配置对象,该对象可选。它的一个作用就是指定
Worker 的名称,用来区分多个 Worker 线程。

2.专用worker中消息的接收和发送

通过postMessage() 方法和onmessage事件处理函数触发workers的方法
若:想要向一个worker发送消息时,你只需要这样做(main.js)
first.onchange = function() {
  myWorker.postMessage([first.value, 1]);
  console.log('Message posted to worker');
}

first代表了元素
当它的值发生改变时,myWorker.postMessage([first.value,value])会将这个值组成数组发送给worker。你可以在消息中发送许多你想发送的东西。

3.在worker中接收到消息后,我们可以写这样一个事件处理函数代码作为响应(worker.js)

onmessage = function(e) {
  console.log('Message received from main script');
  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
  console.log('Posting message back to main script');
  postMessage(workerResult);
}

onmessage处理函数允许我们在任何时刻,一旦接收到消息就可以执行一些代码,代码中消息本身作为事件的data属性进行使用。这里我们简单的对这2个数字作乘法处理并再次使用postMessage()方法,将结果回传给主线程。

4.回到主线程,我们再次使用onmessage以响应worker回传的消息:

myWorker.onmessage = function(e) {
  result.textContent = e.data;
  console.log('Message received from worker');
}

在这里我们获取消息事件的data,并且将它设置为result的textContent,所以用户可以直接看到运算的结果。
注意: 在主线程中使用时,onmessage和postMessage() 必须挂在worker对象上,而在worker中使用时不用这样做。原因是,在worker内部,worker是有效的全局作用域。

5.终止worker

myWorker.terminate()
worker 线程会被立即杀死,不会有任何机会让它完成自己的操作或清理工作。

close();
而在worker线程中,workers 也可以调用自己的 close  方法进行关闭

6.处理错误

当 worker 出现运行中错误时,它的 onerror 事件处理函数会被调用。它会收到
一个扩展了 ErrorEvent 接口的名为 error的事件。

该事件不会冒泡并且可以被取消;为了防止触发默认动作,worker 可以调用错误
事件的 preventDefault()方法。

错误事件有以下三个用户关心的字段:

message
可读性良好的错误消息。
filename
发生错误的脚本文件名。
lineno
发生错误时所在脚本文件的行号。

具体事例可参考链接,该文章中总结了各种场景中使用的情况

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值