如何在 Deno 中实现并发处理

阅读时长 6 分钟读完

如何在 Deno 中实现并发处理

Deno 是 Ryan Dahl 发布的新一代 JavaScript 和 TypeScript 运行时环境,由于它没有 Node.js 中的包管理器,Denoland 社区将会比原本的 npm 社区更稳定和安全。同时,Deno 还内置了模块加载器、安全脚本和 TypeScript 支持、可处理浏览器中的大部分操作、也支持与浏览器的向后兼容。

在本文中,我们将介绍如何在 Deno 中实现并发处理,以便更好地利用多核 CPU,提高应用程序的性能。

  1. 使用 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 继续存在。

  1. 并行化 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

纠错
反馈