最近我一直在研究 Web Worker,这是一份全面的指南,涵盖了开始使用 Web Worker 所需了解的所有内容。
如果您想跳过阅读博客并查看代码,这里是包含所有代码片段的 github 存储库。
Github Web Worker 存储库
所以,促使我探索 Web Workers 的原因是,在我构建的平台中,一项计算繁重的任务会阻塞 UI。
所以我想,‘嗯,好吧,我该如何让它不阻塞 UI’?我是否应该使用 setTimeout 来确保主线程中的所有代码都已执行完毕,然后才能运行计算量大的任务?
所以这是一个误解——使用setTimeout并不意味着UI不会被阻塞。是的,主线程上的所有内容都将在 setTimeout 回调运行之前执行,但是,当该回调从宏任务队列中弹出时,它会在主线程本身中运行,从而使 UI 无响应。
要了解更多有关 setTimeout 如何工作的信息,请参考一些参考资料 —
JavaScript 本质上是一种“单线程语言”,但是 Web Worker 使我们能够在单独的线程中运行计算量大的代码。
在开始之前,有几件事需要注意 -
const worker = new Worker("./worker.js")
注意:worker.js 不是一个模块,不能使用 import 语句。然而。 :')
要将worker.js用作模块,请在构造函数的选项中指定type: module。
const worker = new Worker("./worker.js")
const worker = new Worker('./worker.js', { type: 'module' })
把它们放在一起
现在,让我们看看集成 Web Worker 后我们的代码是什么样子。
主线程代码:
worker.terminate()
工作线程代码:
// ... function workerFunction() { // Don't spin up a new worker instance if the process has already been started. if (statusElement.textContent !== PROCESS_STATUS.PROCESSING && window.Worker) { const worker = new Worker('./worker.js', { type: 'module' }) // Sending 10000000000000 to the web worker worker.postMessage(10000000000000) statusElement.textContent = PROCESS_STATUS.PROCESSING // This piece of code is executed after worker finishes its task and returns data. worker.onmessage = function (event) { statusElement.textContent = event.data } } } // ...
结果:
当我们运行应用程序时,您会注意到执行计算量大的任务时不会阻塞 UI。
Comlink 是一个小型库(1.1kB),它消除了思考 postMessage 逻辑的心理障碍。
在更抽象的层面上,它是 postMessage 和 ES6 代理的 RPC 实现。
我使用 Comlink 的一个具体原因是我无法使用纯 JavaScript 将函数从主线程传递到工作线程。使用 Comlink 的代理,我能够轻松地将回调函数从主线程传递到工作线程。 [参考此部分]
要开始在项目中使用 comlink,请安装库
const worker = new Worker("./worker.js")
要开始使用这个库,我们需要了解以下这些方法 -
Comlink.wrap(端点)
const worker = new Worker('./worker.js', { type: 'module' })
Comlink.expose(值、端点?、allowedOrigins?)
worker.terminate()
延伸阅读
以上是开始之前您需要了解的有关 Web Worker 的所有信息。的详细内容。更多信息请关注PHP中文网其他相关文章!