JavaScript 是一种同步的单线程语言,因此无法充分利用多核 CPU。

尽管如此,它提供了一些机制,允许我们执行某些异步操作并等待它们的响应,而不会阻塞主线程,有时还会阻塞接口。

这篇文章解释了这些机制中的每一种。

尽管有一些方法可以在 JavaScript 中执行异步操作,但有时它们还不够。例如,考虑一个大的for循环,其中需要按照特定顺序执行操作。

我们无法异步执行此操作,甚至无法利用 CPU 的多个内核。好吧,至少,没有。

借助 HTML 5 和现代 Web API,我们现在能够在不阻塞主线程和接口的情况下执行需要大量处理的代码。

今天,我说的是其中之一:Web Workers。

官方规范提到了三种工人:

  • 敬业员工

  • 共享工人

  • 服务人员

Dedicated Workers 由主进程实例化,只能与其通信。

Shared Workers 可以被同源中执行的所有进程访问(不同的浏览器选项卡、iframe 或其他共享工作程序)

Service Workers 是注册到源和路径的面向事件的工作人员。它们能够控制与其相关的网站/页面,拦截和修改导航和资源请求,并以非常精细的方式缓存资源。

来源:https://thecodersblog.com/web-worker-and-implementation


在这篇文章中,我将讨论如何在 VueJS 中实现一个 Dedicated Worker 并使用它来利用多核 CPU。

有一些方法可以在 VueJS 项目中实现 Web Workers:

  • 使用像 vue-worker 这样的插件

  • 实现自定义 webpack 配置

  • 引用一个简单的 JS 文件实例化一个 Worker(我们来说说这个😆)

在 VueJS 项目中实现 Dedicated Web Worker 非常容易。

在 VueJS 中实现一个专用的 Web Worker

1.在你的public文件夹下创建一个.js文件;

  1. 实现一个onmessage函数,接收event作为参数,处理 data* 并在其执行结束时调用postMessage,将结果作为参数传递。

*作为参数传递给这个worker的数据可以从event.data属性中获取。

1、在一个Vue Component中,实例化一个新的Worker,并将最近创建的.js文件的绝对路径作为参数传入其构造函数中。

2、实现onmessageonerror功能。

它们分别是从 Worker 接收到消息时执行的回调,以及在发生任何错误时执行的回调。

  1. 考虑到您需要解决的问题,从您的数据创建块(您可以使用lodash/fp/chunk函数)并对其进行迭代,调用worker.postMessage将块作为参数传递。

这两个文件的结构将类似于:

// ./public/worker.js file

onmessage = function(event) {
  var data = event.data // data sent by the Vue component
is retrieved from 'data' attribute

  var result = doSomething()

  postMessage(result)
}

进入全屏模式 退出全屏模式

// Worker.vue
import { chunk, map } from 'lodash/fp'

export default {
  props: ['data'],
  computed: {
    chunkedData() {
       const size = Math.ceil(this.data.length / 4) // In this case, 4 threads will be created
       return chunk(size, this.data)
    }
  },
  run() {
    const worker = new Worker('/worker.js')

    worker.onmessage = function(event) {
      const data = event.data // Data passed as parameter by the worker is retrieved from 'data' attribute
      console.log(data)
    }

  worker.onerror = console.error // This will be executed in case of any errors

   map(chunk => worker.postMessage(chunk), this.chunkedData)
  }
}

进入全屏模式 退出全屏模式

使用这种结构,您将能够实例化 Web Worker,将数据拆分为块并利用多个线程异步处理每个块,并避免界面和浏览器冻结。

**Obs.:我强烈建议在worker.js文件中使用 ES5 代码。在撰写本文时,Web Workers 中的 ES6+ 代码仍然是未完全支持被所有浏览器所支持。*

您可以在这个 repo中找到此实现的完整示例。

希望你喜欢它!分享和评论。

封面图片来自@helloimnik

Logo

前往低代码交流专区

更多推荐