这篇文章假设您对JavaScript和Vue具有基本知识。
单线程JavaScript
作为一种单线程编程语言,JavaScript一次只能执行一组指令。这意味着其他每个过程都必须等待一个指令在执行下一个过程之前完成。
,如果我们必须执行大量流程并且希望用户仍然能够与应用程序进行交互,这将在我们的Web应用程序中构成速度问题。假设我们需要计算多个投资套餐的投资回报率,并且仍然确保这些过程是非障碍的,并且不会在主线程上运行,因此我们可以在主线程上执行其他任务,例如提出网络请求网络工作者。
注意:阻止是指串行处理 - 一次做一件事情。 另一手代码(异步)的非阻滞可以并行运行(或多线程)
Web工作人员允许我们在背景线程中运行进程,并在完成这些过程完成时通知主线程。这增加了性能的出色提升,因为我们不需要将主线程上的所有内容缩小。
网络工人
Web工作人员是Web内容在背景线程中运行脚本的简单手段。工作线程可以执行任务而不会干扰用户界面。创建后,工人可以将消息发送到JavaScript代码,该消息通过将消息发布给该代码指定的事件处理程序(反之亦然)来创建它。 MDN
JavaScript中的网络工作者
主线程使用工人构造函数创建工人。该构造函数在单个参数中采用了工作文件的路径。该工作文件包含将在工作线程中运行的代码;工人在另一个与当前window
不同的全局上下文中运行。
数据通过消息之间传递在工人和主线程之间 - 主线程和工人线程使用postMessage()
方法发送消息,并使用onmessage
处理程序响应发送消息。
这是在JavaScript中实现Web Worker的一个简单示例。
MartinsOnuoha / js-webworker-example
在JavaScript中使用Webworker的一个简单示例
Webworker Example in JS
A simple illustration on how to use webworkers in javascript.
You can view the example application here
在VUE中使用网络工人
要在VUE应用程序中使用Web Worker,我们可以将Web Worker包装器用于Vue,例如vue-worker软件包,也可以实现低级(从头开始构建)。我将保持简单,并在没有Vue-worker软件包的情况下构建此示例,因此我们了解引擎盖下会发生什么。
让我们设置我们的VUE应用程序。
为了使其简单,我将在平原HTML页面中使用Vue CDN,而不是使用vue-cli生成项目。让我们设置我们的应用程序文件夹。我们的文件夹结构看起来像这样:
应用
我们将在VUE中实现相同的Javascript example(倒数计时器)。由于倒计时计时器是一个长期运行的过程,因此我们将其委派给我们的网络工作者,并在我们的主线程上触发一种方法,以从this API获取随机的狗图像。 like this:
标记
在我们的index.html文件中,我们结构了我们的标记,包括vue-next cdn链接,我们的主脚本文件和vue的安装点。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue-Webworker</title>
<link rel="stylesheet" href="./styles/app.css">
</head>
<body>
<div id="app">
<div class="dog-image">
<img :src="dogImage" v-if="dogImage" />
</div>
<p v-if="counter">{{ counter }}</p>
</div>
<script src="https://unpkg.com/vue@next"></script>
<script src="./script/app.js"></script>
</body>
</html>
我们在顶部导入了CSS文件,并在底部导入脚本。当可用时,我们还将显示来自数据对象的反属性。我们还渲染 dogimage 在可用时使用图像标签的价值。
接下来,我们将在我们的app.js条目文件中设置我们的vue应用。
由于此示例应用程序在很大程度上取决于网络工人,因此我们首先需要检查浏览器是否支持工人,然后我们实例化了一个新的工人类。
if (window.Worker) {
const worker = new Worker('/script/worker.js')
worker.postMessage('')
...
}
接下来,我们设置了我们的应用对象。
const App = {
...
}
我们有两个数据属性:
const App = {
data() {
return {
dogImage: null,
counter: 0,
}
}
}
在我们的方法对象中,我们将创建一种从狗API获取随机狗图像的方法。
...
methods: {
getDogImage () {
fetch('https://dog.ceo/api/breeds/image/random')
.then((response) => response.json())
.then((data) => {
this.dogImage = data.message
})
}
}
...
最后,在安装的钩子中,我们第一次将 getDogiMage 方法拨打从工人线程。我们检查工人发送的计数器价值是否可以除以10;如果是这样,我们将再次称为 getDogiMage 方法。
...
mounted () {
this.getDogImage()
worker.onmessage = (e) => {
this.counter = e.data
if (this.counter % 10 === 0) {
this.getDogImage()
}
}
},
...
然后,我们将应用程序对象安装在#App元素上。
Vue.createApp(App).mount('#app')
整个app.js文件应该看起来像这样:
if (window.Worker) {
const worker = new Worker('/script/worker.js')
worker.postMessage('')
const App = {
data () {
return {
dogImage: null,
counter: 0
}
},
mounted () {
this.getDogImage()
worker.onmessage = (e) => {
this.counter = e.data
if (this.counter % 10 === 0) {
this.getDogImage()
}
}
},
methods: {
getDogImage () {
fetch('https://dog.ceo/api/breeds/image/random')
.then((response) => response.json())
.then((data) => {
this.dogImage = data.message
})
},
showUpdate(e) {
console.log(e)
}
}
}
Vue.createApp(App).mount('#app')
}
在我们的worker.js文件中,我们将设置计数器逻辑,以在重置之前数量高达1000。我们使用后消息方法将新的计数器值发送到主线程,这将由
onmessage = (e) => {
let counter = 0
setInterval(() => {
counter++
if (counter === 1000) {
counter = 0
}
postMessage(counter)
}, 1000)
}
为了获得一些美学,我们会添加一些样式。将其添加到app.css文件中。
body {
background-color: #8EC5FC;
background-image: linear-gradient(62deg, #8EC5FC 0%, #E0C3FC 100%);
}
#app {
text-align: center;
display: flex;
flex-direction: column;
}
p {
font-size: 5rem;
color: #FFF;
}
.dog-image {
width: 100%;
height: 300px;
max-height: 300px;
margin: 0 auto;
}
img {
object-fit: contain;
border-radius: 10px;
}
您可以在VSCODE上使用Liveserver启动应用程序。
您应该找到在port 5500
上运行的应用程序。
查看使用的示例应用程序的source code。
欢呼