多進程 Worker
對於遊戲來說,每幀 16ms 是極其寶貴的,如果有一些可以非同步處理的任務,可以放置於 Worker 中運行,待運行結束後,再把結果返回到主執行緒。
Worker 運行於一個單獨的全域上下文與執行緒中,不能直接呼叫主執行緒的方法。
Worker 與主執行緒之間的資料傳輸,雙方使用Worker.postMessage()來發送數據,Worker.onMessage()來接收數據,傳輸的數據並不是直接共享,而是被複製的。
使用流程
步驟1. 設定 Worker 訊息
在 game.json 中可配置 Worker 程式碼放置的目錄,目錄下的所有 JS 程式碼最終將被打包成一個 JS 檔案:
js
{
"workers": "workers"
}透過上述方式配置,workers 目錄下的所有 JS 文件會被打包為一個 JS 文件,並作為小遊戲首包的一部分。
小遊戲首包體積是有上限的(目前為4M),為了使 worker 程式碼不佔用首包體積,從基礎庫 v2.0.10 開始支援將 worker 程式碼打包為一個分包。 (需更新開發者工具至最新版本)
worker 程式碼配置為分包範例:
js
{
"workers": {
"path": "workers",
"isSubpackage": true // true means the Worker is packaged as a subpackage. Default is false. Setting false is equivalent to { "workers": "workers" }
}
}步驟2. 新增 Worker 程式碼文件
根據步驟1中的配置,在程式碼目錄下新建以下兩個入口檔案:
js
workers / request / index.js;
workers / request / utils.js;
workers / response / index.js;添加後,目錄結構如下:
js
├── game.js
├── game.json
├── project.config.json
└── workers
├── request
│ ├── index.js
│ └── utils.js
└── response
└── index.js步驟3. 編寫 Worker 程式碼
在workers/request/index.js編寫Worker響應代碼
js
const utils = require("./utils");
// In the Worker thread execution context, a global worker object is exposed. Use worker.onMessage/postMessage directly
worker.onMessage(function (res) {
console.log(res);
});步驟4. 在主執行緒中初始化 Worker
在主執行緒的程式碼 game.js 中初始化 Worker。
js
const worker = wx.createWorker("workers/request/index.js"); // Specify the Worker entry file path, absolute path從基礎函式庫 v2.0.10 開始,如果 worker 程式碼配置為了分包,則需要先透過 wx.preDownloadSubpackage 介面下載好 worker 程式碼,再初始化 Worker:
js
var task = wx.preDownloadSubpackage({
packageType: "workers",
success(res) {
console.log("load worker success", res);
var worker = wx.createWorker("workers/request/index.js"); // Create Worker If the Worker subpackage is not fully downloaded, calling createWorker will result in an error
},
fail(res) {
console.log("load worker fail", res);
},
});
task.onProgressUpdate((res) => {
console.log(res.progress); // Monitor download progress using onProgressUpdate
console.log(res.totalBytesWritten);
console.log(res.totalBytesExpectedToWrite);
});步驟5. 主執行緒向 Worker 發送訊息
js
worker.postMessage({
msg: 'hello worker'
})worker 對象的其它介面請查看worker接口说明
注意事項
- Worker 最大並發數量限制為 1 個,建立下一個前請用 Worker.terminate()結束當前 Worker;
- Worker 內程式碼只能 require 指定 Worker 路徑內的文件,無法引用其它路徑;
- Worker 的入口檔案由wx.createWorker()時指定,開發者可動態指定 Worker 入口文件;
- Worker 內不支援 wx 系列的 API;
- Workers 之間不支援發送訊息;
- Worker 目錄內只支援放置 JS 文件,其他類型的靜態文件需要放在 Worker 目錄外。