如何在 Deno 中实现并发处理
Deno 是 Ryan Dahl 发布的新一代 JavaScript 和 TypeScript 运行时环境,由于它没有 Node.js 中的包管理器,Denoland 社区将会比原本的 npm 社区更稳定和安全。同时,Deno 还内置了模块加载器、安全脚本和 TypeScript 支持、可处理浏览器中的大部分操作、也支持与浏览器的向后兼容。
在本文中,我们将介绍如何在 Deno 中实现并发处理,以便更好地利用多核 CPU,提高应用程序的性能。
- 使用 Deno worker 实现并发处理
Deno worker 是一种轻量级的机制,它允许我们在同一个脚本中开启多个线程,从而并行处理任务。Deno worker 是基于 Web Worker 实现的,使用生命周期、事件和 postMessage 等概念。
以下是一个简单的示例代码,实现了一个可以异步下载图片的示例:
-- -------------------- ---- ------- ------ - ------ - ---- -------------------------------------- ----- -------- ----------------------- -------- ------------------- - ----- ------ - --- ------- --- ------------------------- ---------------------- - ----- --------- ----- ----- - -- -------------------- -------- --- ----- - ---- - - ----- ------------------------ ------------------- ------ --- ----------------- - ----- -------- ------ - ----- -------- - ---------------------------- ----- ----------- - ----- ------------------------ ----------------------- ----- ---- ---- ------------------------ - -------
在这个示例中,我们创建了一个 downloadImage 函数,用于异步下载图片。我们使用了 Deno worker 来处理异步任务。Worker 的构造函数接受两个参数:JavaScript 模块的 URL 和可选的选项。我们使用了 ./downloadImage.ts 文件作为 Worker 执行的脚本,使用了 Safe Dynamic Import 语法加载了下载图片的代码。
在 worker 内部,我们通过调用 postMessage
方法,向父线程发送一个请求。在发送请求之后,我们等待 worker 发送回一个响应。在父线程中,我们通过调用 receiveMessage
方法,等待 worker 发送的消息。在这个部分,我们将 worker 终止,在返回响应数据之前,因为我们不想 worker 继续存在。
- 并行化 CPU 密集型任务
利用 Deno worker 实现异步调用,对于网络 I/O 密集型操作非常有用。而对于 CPU 密集型操作而言,开启多线程会更好地利用多核 CPU。
下面是一个示例代码,它实现了一个并行化求素数的函数:
-- -------------------- ---- ------- ------ - ------ - ---- -------------------------------------- ----- -------- -------------------------- ------- ------- -------- ----------------- - ----- ---------- - ---- ----- -------- -------- - --- ----- ------- -------- - --- -- -- ------ -------- --- ---- - - --------- - -- ------- - -- ----------- - ----- ------ - --- ------- --- ---------------------- ---------------------- - ----- --------- ----- ----- - -- -------------------- ------ -- ---- ---------- - ---------- - -- ------- --- --------------------- - -- ---- ------ -- ----- ------- - ----- --------------------------------------- -- -------------------------- -- -- ------ ----- --- ------ ------ -- -------- - -- -------------- --- ----------- - ----------------------------- - ---- - ----------------------------- - - -- ---- ------ --- ------ ------ -- -------- - ------------------- - ------ ------- - ----- -------- ------ - ----- ------------ - ----- ------------------- ------- ------------------ ---------------------- ----- ----------- - -------
在这个示例中,我们创建了一个 findPrimeNumbers
函数,它返回一段范围内的所有素数。我们使用 CHUNK_SIZE 变量将任务切割为块,每个 worker 处理 500 个数字的求素数问题。我们使用 Promise.allSettled 函数等待所有 workers 完成,并返回处理结果。如果 worker 失败,我们将它的错误消息记录下来。在最后,我们终止所有的 worker。
注意:在 Deno 的 worker 中,不支持共享内存,你需要使用 MessageChannel 完成不同线程之间的通信。
总结
在本文中,我们学习了如何在 Deno 中实现并发处理。我们利用 Deno worker 实现了异步调用,并利用多线程并行化处理 CPU 密集型任务。当然,在从单线程应用程序迁移到多线程应用程序时,你需要谨慎考虑应用程序的复杂度和性能。我们建议你在实际开发中,使用性能分析工具来检查单线程和多线程应用程序之间的性能差异。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/654e093c7d4982a6eb75b93a