webworker全面解读(保姆级)

当你开始更加注重代码运行可控,更加在意页面性能,给予用户神一般的浏览体验时,很希望你可以从本文中找到一点线索。

背景以及含义

JavaScript的单线程,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。 这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定JavaScript同时有两个线程,一个线程在某个DOM节点上添加内容,另一个线程删除了这个节点,这时浏览器将不知以哪个线程为准。明白了吧兄弟姐妹,也就是单线程是指Js引擎执行Js时只分了一个线程给他执行,也就是执行js时是单线程的。

由于JavaScript是单线程的,程序员不必担心并发问题,不需要关注线程间的同步和锁,这使得代码编写更加简单易用。但是,这种单线程设计有一些缺点,主要体现在以下几个方面:

  • 阻塞: JavaScript 在执行某个任务时会阻塞整个线程,因此如果某个任务需要大量计算或者网络请求等耗时操作,就会导致页面的响应时间变慢甚至出现卡顿现象。

  • 难以利用多核CPU: 由于JavaScript 是单线程的,因此无法利用多核CPU 的优势,这使得在处理大量数据或者进行复杂计算时效率低下。

  • 不适合CPU密集型任务: 由于JavaScript 是单线程的,因此对于CPU 密集型任务(例如视频编码、图像处理等),JavaScript 的执行效率较低。

  • 难以处理大量并发请求: 由于JavaScript 的单线程特性,无法同时处理多个请求,这使得在处理大量并发请求时,JavaScript 的执行效率较低。

  • 容易出现死锁: 由于JavaScript 的单线程特性,当某个任务长时间占用线程时,其他任务就会被阻塞,这可能会导致死锁的发生。

  • 无法实现真正的并行: 由于JavaScript 是单线程的,因此无法真正地实现并行,而只能通过异步编程方式模拟并行。这种模拟方式需要使用回调、Promise、async/await 等技术,代码复杂度较高,也容易出现回调地狱等问题。

所以,webworker横空出世!
在这里插入图片描述

在Web Worker标准中,定义了解决客户端JavaScript无法多线程的问题,其中定义的 " Worker " 是指执行代码的并行线程,不过,Web Worker处在一个自包含的执行环境中,无法访问Window对象和Document对象,和主线程之间的通信也只能通过异步消息传递机制实现,这就意味着,并行的修改DOM是不可能的。不过因为worker一旦新建,就会一直运行,不会被主线程的活动打断,这样有利于随时响应主线程的通性,但是也会造成资源的浪费,所以不应过度使用,用完注意关闭。尽管Web Worker曾经存在兼容性问题,但是现在基本解决,现在几乎唯一的缺点就是会占用内存。

使用

  • 在主线程中
//创建worker
var myWorker = new Worker(文件路径);

//worker和主线程都可以通过postMessage来给对方发送消息,也可以用onmessage来接收对方发送的消息。
myWorker.postMessage(发送的消息);
myWorker.onmessage=(收到的消息)=>{}

//指定worker线程发生错误时的回调
myWorker.onerror=()=>{}//关闭worker
myWorker.terminate();
  • 在worker线程中,Worker线程中全局对象为 self,代表子线程自身,这时 this指向self,所以不写self也可以,其上有一些api:
//worker 线程往主线程发消息,消息可以是任意类型数据,包括二进制数据
self.postMessage(发送的消息);

//指定主线程发worker线程消息时的回调
self.onmessage=(收到的消息)=>{}; 

//worker线程关闭自己
self.close();

//指定worker线程发生错误时的回调
self.onerror=()=>{}//加载 JS 脚本(同步加载)
self.importScripts('script1.js', 'script2.js'...);

注意事项

  • 主线程与 Worker 之间的通信内容,可以是文本,也可以是对象。需要注意的是,这种通信是拷贝关系,即是传值而不是传址,Worker 对通信内容的修改,不会影响到主线程。事实上,浏览器内部的运行机制是,先将通信内容串行化,然后把串行化后的字符串发给 Worker,后者再将它还原。
  • worker脚本与主进程的脚本必须遵守同源限制。他们所在的路径协议、域名、端口号三者需要相同。
  • 无法加载本地js文件,必须使用线上。Worker 线程无法读取本地文件,即不能打开本机的文件系统(file://),它所加载的脚本,必须来自网络。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值