IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 学习webworker -> 正文阅读

[JavaScript知识库]学习webworker

1. 什么是webworker

理论多代码少的一个新特性

MDN是这样说的

Web WorkerWeb内容在后台线程中运行脚本提供了一种简单的方法。线程可以执行任务而不干扰用户界面

一个worker是使用一个构造函数创建的一个对象(e.g. Worker()) 运行一个命名的JavaScript文件

这个文件包含将在工作线程中运行的代码;

workers 运行在另一个全局上下文中,不同于当前的window

因此,使用 window快捷方式获取当前全局的范围 (而不是self) 在一个 Worker 内将返回错误

可以这样理解:

  1. 创建Worker时,JS引擎向浏览器申请开一个子线程(子线程是浏览器开的,完全受主线程控制,而且不能操作DOM
  2. JS引擎线程与worker线程间通过特定的方式通信(postMessage API,需要通过序列化对象来与线程交互特定的数据)

如果有非常耗时的cpu密集型工作,可以单独开一个Worker线程,因为里面不管如何翻天覆地都不会影响JS引擎主线程,
只待计算出结果后,将结果通信给主线程即可

而且注意下,JS引擎是单线程的,这一点的本质仍然未改变,Worker可以理解是浏览器给JS引擎开的外挂,专门用来解决那些大量计算问题。

2. webworker帮助我们解决了什么问题,该如何去使用webworker呢

一些非常耗时的工作会阻塞js的代码,这种情况就需要使用这个东西。
非常耗时的cpu密集型工作!!!

举个例子:我们在两个button中间加一段耗时的script代码。

	<body>
	  <button>111</button>
	  <script src="./1.js"></script>
	  <button>222</button>
	</body>

1.js的耗时代码:

	var start = new Date().getTime()
	
	do {
	  var end = new Date().getTime();
	} while (end - start < 3000)
	console.log("5秒执行结束");

这里我们一般不这样写代码,但是确实一个很好的线程阻塞的问题,因为js的单线程,浏览器的渲染引擎将第一个button渲染结束的时候,执行了script脚本,cpu被js引擎占用,如果这个耗时操作不结束,渲染引擎将无法继续工作,导致页面不能正常的工作。

A. 开启worker

我们这个时候开启一个Worker即可解决这个问题。(注意这个不能读取本地的js文件,否则会报错,只能是服务端的js脚本文件)

	<body>
	  <button>111</button>
	  <script>
	    // 创建新的线程执行05.js
	    var worker= new Worker("./1.js")
	  </script>
	  <button>222</button>
	</body>

只是执行代码还是有些单薄的,我们还需要实现主线程与worker线程之间的通讯

B. 主线程 -> worker线程

主线程调用worker.postMessage()方法,向 Worker 发消息

	worker.postMessage('Hello World');
	worker.postMessage({method: 'echo', args: ['Work']});

主线程通过worker.onmessage指定监听函数,接收子线程发回来的消息。

	worker.onmessage = function (event) {
	  console.log('Received message ' + event.data);
	  doSomething();
	}
	
	function doSomething() {
	  // 执行任务
	  worker.postMessage('Work done!');
	}

Worker 完成任务以后,主线程就可以把它关掉

	worker.terminate();

填坑举例:这个监听一般都是异步的所以我们在主线程关闭的时候要在onmessage中将数据处理完成之后关闭。

    // 创建新的线程执行05.js
    var worker = new Worker("./1.js")

    // 向worker发数据
    worker.postMessage("123")

    // 接收worker的数据
    worker.onmessage = function(event) {
      console.log("主Received message:" + event.data);
      wworkerterminate();
    }
    // w.terminate(); // 消息无法正常的传递,我们在传递前就关掉了

C. worker线程 -> 主线程

Worker 线程内部需要有一个监听函数,监听message事件,监听从主线程来的消息

	self.addEventListener('message', function (e) {
	  self.postMessage('You said: ' + e.data);
	}, false);

上面代码中,self代表子线程自身,即子线程的全局对象。因此,等同于下面两种写法。

	// 写法一
	this.addEventListener('message', function (e) {
	  this.postMessage('You said: ' + e.data);
	}, false);
	
	// 写法二
	addEventListener('message', function (e) {
	  postMessage('You said: ' + e.data);
	}, false);

子线程调用worker.postMessage()方法,向 主线程发消息

  postMessage("456")

子线程接收主线程的消息,并且发送给主线程结果,然后关闭自己

	onmessage = function(event) {
	  console.log("新Received message:" + event.data);
	  postMessage("456")
	  self.close()
	}

子线程关闭自己

	self.close();

D. 关闭 Worker

使用完毕,为了节省系统资源,必须关闭 Worker。

	// 主线程
	worker.terminate();
	
	// Worker 线程
	self.close();

以上就已经完成了worker最基本的使用了。

还在阮一峰老师的博客上看到其他的两个方法在这里搬运一下

1. 在 Worker 内加载脚本

Worker 内部如果要加载其他脚本,有一个专门的方法importScripts()。

	importScripts('script1.js');

该方法可以同时加载多个脚本。

	importScripts('script1.js', 'script2.js');

2. 错误处理

主线程可以监听 Worker 是否发生错误。如果发生错误,Worker 会触发主线程的error事件。

	worker.onerror(function (e) {
	  console.log([
	    'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
	  ].join(''));
	});
	
	// 或者
	worker.addEventListener('error', function (e) {
	  // ...
	});

到这里,最基本的webworker的使用就结束了,希望大家能有所收获。

参考文档:
进程线程:https://segmentfault.com/a/1190000012925872
阮一峰:https://www.ruanyifeng.com/blog/2018/07/web-worker.html

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-07 11:56:25  更:2021-12-07 11:57:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:26:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码