本文最后更新于 1701 天前,其中的信息可能已经有所发展或是发生改变。
Table of Content
背景
页面中的JavaScript是在单一线程中运行的。若页面代码的逻辑过于复杂、或者存在密集计算的情况,容易阻塞其他的方法运行。
对于目前大多数计算机都使用多核CPU,使用单线程模型浪费了许多计算资源。
而Web Worker给了我们一种新的解决办法。
开始
需要的依赖
* worker-loader
* typescript
* promise-worker
npm i -D worker-loader promise-worker
将下列加入vue.config.js
中
configureWebpack: config => {
const configs = {
plugins: [
new MonacoEditorPlugin()
],
module: {
rules: [
{
test: /\.web\.worker\.ts$/,
use: {
loader: "worker-loader",
options: {
inline: true,
publicPath: "/"
}
}
},
{
test: /\.web\.worker\.ts$/,
use: ["ts-loader"],
exclude: /node_modules/
}
]
}
};
return configs;
},
然后,这里以CUP-Online-Judge-NG-FrontEnd举例。
在这里,我们把markdownIt封装为Web Worker, 如下:
import registerPromiseWorker from "promise-worker/register";
import MarkdownIt from "@/lib/markdownIt/markdownIt";
registerPromiseWorker((message) => {
if (message.type === "render") {
return MarkdownIt.render(message.content);
}
else if (message.type === "renderRaw") {
return MarkdownIt.renderRaw(message.content);
}
});
export default {} as typeof Worker & {new (): Worker};
注意 最后要export default {} as typeof Worker & {new (): Worker};
,否则会提示没有default module导出。
然后,在需要Web Worker的地方这样用
import Vue from "vue";
import { Component } from "vue-property-decorator";
import PromiseWorker from "promise-worker";
import Worker from "@/worker/markdown.web.worker";
@Component
export default class MarkdownWorkerMixin extends Vue {
originalWorker = new Worker();
worker_!: PromiseWorker;
created () {
this.worker_ = new PromiseWorker(this.originalWorker);
}
beforeDestroy () {
this.originalWorker.terminate();
}
async renderAsync (content: string) {
return this.worker_.postMessage({
type: "render",
content
});
}
async renderRawAsync (content: string) {
return this.worker_.postMessage({
type: "renderRaw",
content
});
}
}
这里我们整合promise-worker,方便调用Web Worker的异步方法。
这样就能够通过postMessage
像worker发送请求,而该方法返回一个Promise,携带返回的结果。
需要注意的是,这个写法需要关闭parallel
,即不能开启并行编译,否则会出现错误。
即
vue.config.js
module.exports = {
// some code
parallel: false
}