Deno 入門指南
  • 前言
  • Deno 更新日誌
  • 簡介
    • Deno 跟 Node.js 的主要差異
    • Hello, World!
  • TypeScript 基礎篇
    • 變數宣告
    • 使用型別系統
    • 流程判斷與迴圈
    • 函式宣告
    • This 與 Arrow Function
    • 在函式中應用強型別
    • 介面
    • 型別別名
    • 物件導向概念
    • 類別的封裝與繼承
    • 介面與類別、抽象類別
    • 泛型的概念與實作
    • 型別補充
  • Deno CLI
    • 快速開始
    • 沙盒機制
    • URL Import
    • 編譯選項
    • 相關工具及測試
      • WebGPU API
      • Deno.resolveDns
      • 程式碼編譯器
      • 程式碼檢查器
      • 依賴檢查器
      • 文件產生器
      • 程式碼打包工具
      • 腳本安裝
      • 程式碼格式化
      • Deno 命名空間與編譯器 API
      • 使用 Deno 進行測試
  • 使用 Deno 打造多線程應用
    • 多線程概念
    • Deno Workers
    • 使用多線程計算矩陣相乘
  • 使用 Deno 打造 Web API
    • Web API 介紹
    • Oak 框架介紹
    • 使用 Denon 精簡指令
    • 實作 Web API
    • MongoDB 安裝教學
    • Deno 與 MongoDB 共舞
    • 完成第一支 Web API
    • 淺談跨來源資源共用(CORS)與解決辦法
Powered by GitBook
On this page
  • 多線程在 Deno 上有任何限制嗎?
  • 延伸閱讀

Was this helpful?

  1. 使用 Deno 打造多線程應用

Deno Workers

Previous多線程概念Next使用多線程計算矩陣相乘

Last updated 4 years ago

Was this helpful?

在暸解何謂多線程以後,我們來看看要如何在 Deno 開發多線程的程式吧!

Deno 支援 , Workers 可以讓程式運作在多個線程上,而每一個 Worker 實體都在獨立的線程上運作。

目前為止,Deno 只支持 module 類型的 Worker 。因此,在初始化新的 Worker 實體時需要加入 type option :

new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });

需要注意的是: Deno 目前相對模塊說明符 。使用者可以改用 URL 構造器並使用 import.meta.url 引入本地端的程式碼。

// Good
new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });

// Bad
new Worker(new URL("worker.js", import.meta.url).href);
new Worker(new URL("worker.js", import.meta.url).href, { type: "classic" });
new Worker("./worker.js", { type: "module" });

舉例來說,有一個主程式碼 main.ts 以來用來派發的工作程式碼 worker.ts :

// main.ts
new Worker(new URL("worker.ts", import.meta.url).href, { type: "module" });
// worker.ts
console.log("hello world");
self.close();

因為執行 main.ts 時會有讀取 worker.ts 的動作,所以要記得加入 --allow-read 標籤:

deno run --allow-read main.ts

載入遠端模組

現在,讓我們來嘗試將 worker.ts 移動到遠端上:

// main.ts
new Worker("https://example.com/worker.ts", { type: "module" });

因為有網路存取需求,執行時需要加入 --allow-net :

deno run --allow-net main.ts

將腳本發布到 gist

筆者嘗試將程式碼丟到 gist 上:

// main.ts
new Worker("https://gist.githubusercontent.com/ianchen0119/5935736ab973fcbcbbbb5294d8bd2655/raw/a94a6547d8b66f50441f4cef8a5218ab19b49c11/worker.ts", { type: "module" });

gist 上的程式碼:

await console.log("hello world");
self.close();

執行時同樣需要加入 --allow-read 標籤唷!

眼尖的讀者應該有發現該範例在 console.log("hello world"); 前面多了一個 await 。

傳遞參數

Workers 也可以讓我們將需要的參數傳入要派發的任務( Worker.ts )當中:

// main.js
const worker = new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });
worker.postMessage('Hello World!');
// worker.js
self.onmessage = async (e) => {
	let { data } = e;
	console.log(data);
	self.close();
  };

在 worker 中使用 Deno

一般情況下,命名空間 Deno 在 Worker 範圍內是不可用的。

不過我們可以利用 deno: true 選項做到這點:

// main.js
const worker = new Worker(new URL("worker.js", import.meta.url).href, {  type: "module",  deno: true,});
worker.postMessage({ filename: "./log.txt" });
// worker.js
self.onmessage = async (e) => {
  const { filename } = e.data;  
  const text = await Deno.readTextFile(filename);  
  console.log(text);  
  self.close();
};

由於該功能還不穩定,執行時需要加入 --unstable 旗標:

$ deno run --allow-read --unstable main.js

補充:當 Deno 命名空間在 Worker 作用域中可用時,將會繼承 main.js 的權限(使用--allow-*標誌指定的權限)。

多線程在 Deno 上有任何限制嗎?

There are no limits, you can create as many as you want Again, there are no limits. We now have facilities to set heap limits on the isolate, but it's not possible to set them for workers.

在這邊提供給有需要的讀者做參考。

延伸閱讀

同樣的事情在不同人眼中可能會有不同的見解、看法。

在讀完本篇以後,筆者也強烈建議大家去看看以下文章,或許會對型別、變數宣告...等觀念有更深層的看法唷!

Github 有提供 服務,讓開發者可以張貼自己的程式碼,方便分享或是用於撰寫技術文章。

可以參考 。

筆者在 Deno 的 Github Repo 上了關於多執行緒的問題,主要提到 Deno 是否有限制執行緒的數量以及每條執行緒是否有記憶體限制, Deno 的主要貢獻者回答:

Web Worker API
不支持
gist
Link
公開發問
Deno Manual