Web Worker的理解以及使用

1、 为什么使用

(1)可视化项目中有些数据需要频繁更新,有的图表类型的数据若要达到不卡顿流畅显示则需要毫秒级的更新频率。因此,Web Worker 就成为了我解决这类问题的较好解决方法。
(2)Js 为单线程,而Web Worker 允许JavaScript 创建多个线程,它允许开发人员编写能够长时间运行而不被用户所中断的后台程序,去执行事务或者逻辑,并同时保证页面对用户的响应。简而言之,就是允许JavaScript创建多个线程,但是子线程完全受主线程控制。

2、 概述&作用

Web Workers 使得一个Web应用程序可以在与主执行线程分离的后台线程中运行一个脚本操作。这样做的好处是可以在一个单独的线程中执行费时的处理任务,从而允许主(通常是UI)线程运行而不被阻塞。
作用就是给JS创造多线程运行环境,允许主线程创建worker线程,分配任务给后者,主线程运行的同时worker线程也在运行,相互不干扰,在worker线程运行结束后把结果返回给主线程。这样做的好处是主线程可以把计算密集型或高延迟的任务交给worker线程执行,这样主线程就会变得轻松,不会被阻塞或拖慢。这并不意味着JS语言本身支持了多线程能力,而是浏览器作为宿主环境提供了JS一个多线程运行的环境。
不过因为worker一旦新建,就会一直运行,不会被主线程的活动打断,这样有利于随时响应主线程的通性,但是也会造成资源的浪费,所以不应过度使用,用完注意关闭。

3、 限制&注意点

(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请求。

4、使用

1、 主线程

(1) 创建

主线程采用new命令,调用Worker()构造函数,新建一个 Worker 线程

var myWorker = new Worker('work.js');

(2) 发送消息&接收消息

worker和主线程都可以通过postMessage来给对方发送消息,也可以用onmessage来接收对方发送的消息。

const first = document.querySelector('#number1');
const second = document.querySelector('#number2');
const result = document.querySelector('.result');
if (window.Worker) {
    const myWorker = new Worker("worker.js");
    first.onchange = function() {
      myWorker.postMessage([first.value, second.value]);
      console.log('Message posted to worker');
    }
    second.onchange = function() {
      myWorker.postMessage([first.value, second.value]);
      console.log('Message posted to worker');
    }
    myWorker.onmessage = function(e) {
        result.textContent = e.data;
        console.log('Message received from worker');
    }
} else {
    console.log('Your browser doesn\'t support web workers.')
}

(3) 关闭

myWorker.terminate();

2、 Worker线程

Worker线程中全局对象为 self,代表子线程自身,这时 this指向self,其上有一些api:
self.postMessage: worker 线程往主线程发消息,消息可以是任意类型数据,包括二进制数据
self.close: worker线程关闭自己
self.onmessage: 指定主线程发worker线程消息时的回调,也可以这样写self.addEventListener(‘message’,cb)
self.onerror: 指定worker线程发生错误时的回调,也可以这样写 self.addEventListener(‘error’,cb)
self.importScripts(): 加载 JS 脚本

(1) 创建

Worker 线程内部需要有一个监听函数,监听message事件

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

(2)根据主线程发送的消息,worker线程可以调用不同的方法

1. self.addEventListener('message', function (e) {
2.   var data = e.data;
3.   switch (data.cmd) {
4.     //开始工作
5.     case 'start':
6.       self.postMessage('WORKER STARTED: ' + data.msg);
7.       break;
8.     //结束线程
9.     case 'stop':
10.       self.postMessage('WORKER STOPPED: ' + data.msg);
11.       self.close(); // Terminates the worker.
12.       break;
13.     default:
14.     //发送消息
15.       self.postMessage('Unknown command: ' + data.msg);
16.   };
17. }, false);

(3)错误处理-

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

self.close();

5、实战场景

1、加密数据

有些加解密的算法比较复杂,或者在加解密很多数据的时候,这会非常耗费计算资源,导致UI线程无响应,因此这是使用Web Worker的好时机,使用Worker线程可以让用户更加无缝的操作UI。

2、预取数据

有时候为了提升数据加载速度,可以提前使用Worker线程获取数据,因为Worker线程是可以是用 XMLHttpRequest 的。

3、预渲染

在某些渲染场景下,比如渲染复杂的canvas的时候需要计算的效果比如反射、折射、光影、材料等,这些计算的逻辑可以使用Worker线程来执行,也可以使用多个Worker线程,这里有个https://link.zhihu.com/?target=https%3A//nerget.com/rayjs-mt/rayjs.html。

4、复杂数据处理场景

某些检索、排序、过滤、分析会非常耗费时间,这时可以使用Web Worker来进行,不占用主线程。

5、预加载图片

有时候一个页面有很多图片,或者有几个很大的图片的时候,如果业务限制不考虑懒加载,也可以使用Web Worker来加载图片。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
nginx是一个高性能的Web服务器,同时也是一个反向代理服务器和电子邮件(IMAP/POP3)代理服务器。它最显著的特点是具有高并发处理能力和低内存占用。为了满足不同用户的需求,nginx提供了模块化的架构,可以通过开发模块来扩展其功能。 深入理解nginx模块开发,首先需要了解nginx的架构。nginx的主要部分包括master进程和worker进程。master进程负责管理worker进程,而worker进程负责处理实际的客户端请求。nginx的模块系统允许开发者向master进程或worker进程添加自定义的功能。 在nginx的模块开发中,主要涉及到以下几个方面的内容: 1. 配置文件解析:nginx的配置文件是使用类似于C语言的语法进行解析的。模块开发者需要了解nginx的配置文件语法,并且能够解析和处理自定义的配置项。 2. HTTP请求处理:开发基于HTTP协议的模块时,需要能够处理和解析HTTP请求。模块可以拦截特定的URL,处理请求,并返回相应的响应。 3. 事件处理:nginx使用事件驱动的模型来处理并发请求。模块开发者需要了解事件驱动的机制,实现自己的事件处理逻辑,并与nginx的事件处理系统进行交互。 4. 内存管理:nginx以低内存占用著称,这是因为它使用了自己的内存管理机制。模块开发者需要了解nginx的内存管理方式,并遵循相应的规则。 5. 日志记录:nginx提供了灵活的日志记录功能。模块开发者可以通过定制日志记录方式,将特定的信息记录到指定的日志文件中。 总的来说,深入理解nginx模块开发与架构解析需要对nginx的整体架构有深入了解,并具备一定的系统编程和网络编程经验。通过开发和调试模块,可以进一步理解nginx的原理和内部实现,掌握更多高性能Web服务器开发的知识和技巧。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值