首页 > 其他分享 >使用 web workers 及 基本原理 和 应用场景

使用 web workers 及 基本原理 和 应用场景

时间:2023-01-07 16:12:37浏览次数:78  
标签:web 基本原理 workers worker js --- Worker 线程 消息

众所周知,Javascript是运行在单线程环境中,也就是说无法同时运行多个脚本。假设用户点击一个按钮,触发了一段用于计算的Javascript代码,那么在这段代码执行完毕之前,页面是无法响应用户操作的。但是,如果将这段代码交给Web Worker去运行的话,那么情况就不一样了:浏览器会在后台启动一个独立的worker线程来专门负责这段代码的运行,因此,页面在这段Javascript代码运行期间依然可以响应用户的其他操作。

Web Worker简介
Web Worker 是HTML5标准的一部分,这一规范定义了一套 API,它允许一段JavaScript程序运行在主线程之外的另外一个线程中。
值得注意的是, Web Worker 规范中定义了两类工作线程,分别是专用线程Dedicated Worker和共享线程 Shared Worker,其中,Dedicated Worker只能为一个页面所使用,而Shared Worker则可以被多个页面所共享。

Web Worker 使用注意如下常见的几点:

同源限制:分配给 Worker线程运行的脚本文件,必须与主线程的脚本文件同源。2. DOM限制:Worker所在的线程它不能操作window,document这样的对象,也就是说worker线程不能操作dom对象,但是worker线程可以操作业务逻辑,然后把操作后的结果返回给主线程,主线程再去做相关的DOM操作。

文件限制:Worker线程无法读取本地文件,也就是说不能打开本机的文件系统(如:file://) 这样的,它所加载的脚本,必须来自网络。

1.在webpack中配置 Web Workers

|--- web-worker项目
| |--- node_modules          # 安装的依赖包
| |--- public
| | |--- images              # 存放项目中所有的图片
| | |--- js
| | | |--- main.js           # js 的入口文件
| | | |--- test1.worker.js   # worker 线程的js文件
| | |--- styles              # 存放所有的css样式
| | |--- index.html          # html文件
| |--- package.json
| |--- webpack.config.js
  1. 在项目中安装 worker-loader 依赖,如下命令所示
  2. 在webpack配置中添加如下配置:
    module.exports = {
      module: {
        rules: [
          {
            test: /\\.worker\\.js$/, // 以 .worker.js 结尾的文件将被 worker-loader 加载
            use: {
              loader: 'worker-loader',
              options: {
                inline: true
                // fallback: false
              }
            }
          }
        ]
      }
    }

    如上正则匹配的是以 以 .worker.js 结尾的文件将被 worker-loader 加载, 也就是说我们在项目中我们的worker文件名可以叫 test.worker.js 类似这样的名字,或其他的,只要保证 xxx.worker.js 这样的文件名即可。

    在上面配置中,设置 inline 属性为 true 将 worker 作为 blob 进行内联;内联模式将额外为浏览器创建 chunk,即使对于不支持内联 worker 的浏览器也是这样的;

   在本地开发中,我们会使用 webpack-dev-server 启动本地调式服务器,如果只有上面的配置的话,我们可以在控制台中会报如下的错误

    "Uncaught ReferenceError: window is not defined";

   要解决如上的错误的话,我们需要在我们的webpack配置文件下的out下,加一个属性 globalObject: 'this'; 如下代码:
   module.exports = { output: { globalObject: 'this' } }

module.exports = {
  output: {
    filename: process.env.NODE_ENV === 'production' ? '[name].[contenthash].js' : '[name].js',
    // 将输出的文件都放在dist目录下
    path: path.resolve(__dirname, 'dist'),
    publicPath: '/',
    globalObject: 'this'
  }
}

来看下我们的 public/js/main.js 代码如下:

// 加载css样式
require('../styles/main.styl');
 
import Worker from './test1.worker.js';
 
// 创建worker实列
var worker = new Worker();
 
// 向worker线程发送消息
worker.postMessage('主线程向worker线程发送消息');
 
// 监听worker线程发送回来的消息
 
worker.onmessage = function(e) {
  console.log('监听worker线程发送回来的消息如下所示:')
  console.log(e);
};

public/js/test1.worker.js(子线程)的代码如下所示:

// 监听消息
onmessage = function(e) {
  console.log('监听到的消息为:' + e.data);
}
 
const msg = '工作线程向主线程发送消息';
 
// 发送消息
postMessage(msg);

运行如下

 

 

如上代码,我们首先创建了一个worker实列,如代码:var worker = new Worker(); 然后他就会调用 test1.worker.js 代码,该worker中的代码会首先给主线程发送消息,消息文本为: '工作线程向主线程发送消息'; 然后我们的主线程中会通过 worker.onmessage 事件来监听子线程的消息,因此我们第一次打印出来为如下代码的消息:

worker.onmessage = function(e) { console.log('监听worker线程发送回来的消息如下所示:') console.log(e); };

然后我们的主线程才会向子线程发送消息,如下代码:

// 向worker线程发送消息 worker.postMessage('主线程向worker线程发送消息');

然后 test1.worker.js 代码中的 onmessage 就能监听到消息,如下所示:

// 监听消息 onmessage = function(e) { console.log('监听到的消息为:' + e.data); }

最后就会打印出信息如下:"监听到的消息为:主线程向worker线程发送消息"。

标签:web,基本原理,workers,worker,js,---,Worker,线程,消息
From: https://www.cnblogs.com/xgn666/p/17032837.html

相关文章