# @ohos.worker (启动一个 Worker)
说明:
本模块首批接口从 API version 7 开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。
Worker 是与主线程并行的独立线程。创建 Worker 的线程称之为宿主线程,Worker 自身的线程称之为 Worker 线程。创建 Worker 传入的 url 文件在 Worker 线程中执行,可以处理耗时操作但不可以直接操作 UI。
# 导入模块
import worker from "@ohos.worker";
# 属性
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
parentPort | DedicatedWorkerGlobalScope | 是 | 是 | worker 线程用于与宿主线程通信的对象。 |
# WorkerOptions
Worker 构造函数的选项信息,用于为 Worker 添加其他信息。
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
name | string | 是 | 是 | Worker 的名称。 |
# Worker
使用以下方法前,均需先构造 Worker 实例,Worker 类继承EventTarget。
# constructor
constructor(scriptURL: string, options?: WorkerOptions)
Worker 构造函数。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
scriptURL | string | 是 | Worker 执行脚本的路径。 在 FA 和 Stage 模型下,DevEco Studio 新建 Worker 工程路径分别存在以下两种情况: (a) worker 脚本所在目录与 pages 目录同级。 (b) worker 脚本所在目录与 pages 目录不同级。 |
options | WorkerOptions | 否 | Worker 构造的选项。 |
返回值:
类型 | 说明 |
---|---|
Worker | 执行 Worker 构造函数生成的 Worker 对象,失败则返回 undefined。 |
示例:
import worker from "@ohos.worker";
// worker线程创建
// FA模型-目录同级
const workerFAModel01 = new worker.Worker("workers/worker.js", {
name: "first worker in FA model",
});
// FA模型-目录不同级(以workers目录放置pages目录前一级为例)
const workerFAModel02 = new worker.Worker("../workers/worker.js");
// Stage模型-目录同级
const workerStageModel01 = new worker.Worker("entry/ets/workers/worker.ts", {
name: "first worker in Stage model",
});
// Stage模型-目录不同级(以workers目录放置pages目录后一级为例)
const workerStageModel02 = new worker.Worker(
"entry/ets/pages/workers/worker.ts"
);
// 理解Stage模型scriptURL的"entry/ets/workers/worker.ts":
// entry: 为module.json5文件中module的name属性对应的值;
// ets: 表明当前使用的语言。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
同时,需在工程的模块级 build-profile.json5 文件的 buildOption 属性中添加配置信息,主要分为下面两种情况:
(1) 目录同级( 不添加也可以 )
FA 模型:
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/MainAbility/workers/worker.ts"
]
}
}
2
3
4
5
6
7
Stage 模型:
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/worker.ts"
]
}
}
2
3
4
5
6
7
(2) 目录不同级( 必须添加 )
FA 模型:
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/worker.ts"
]
}
}
2
3
4
5
6
7
Stage 模型:
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/pages/workers/worker.ts"
]
}
}
2
3
4
5
6
7
# postMessage
postMessage(message: Object, options?: PostMessageOptions): void
向 Worker 线程发送数据,数据类型必须是序列化所支持的类型。序列化支持类型见其他说明。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
message | Object | 是 | 发送至 Worker 的数据。 |
options | PostMessageOptions | 否 | 可转移对象是 ArrayBuffer 的实例对象。transferList 数组中不可传入 null。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.postMessage("hello world");
var buffer = new ArrayBuffer(8);
workerInstance.postMessage(buffer, [buffer]);
2
3
4
5
6
# on
on(type: string, listener: EventListener): void
向 Worker 添加一个事件监听。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | string | 是 | 监听的事件类型。 |
listener | EventListener | 是 | 回调事件。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.on("alert", (e) => {
console.log("alert listener callback");
});
2
3
4
# once
once(type: string, listener: EventListener): void
向 Worker 添加一个事件监听,事件监听只执行一次便自动删除。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | string | 是 | 监听的事件类型。 |
listener | EventListener | 是 | 回调事件。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.once("alert", (e) => {
console.log("alert listener callback");
});
2
3
4
# off
off(type: string, listener?: EventListener): void
删除类型为 type 的事件监听。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | string | 是 | 需要删除的事件类型。 |
listener | EventListener | 否 | 删除的回调事件。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.off("alert");
2
# terminate
terminate(): void
销毁 Worker 线程,终止 Worker 接收消息。
系统能力: SystemCapability.Utils.Lang
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.terminate();
2
# onexit
onexit?: (code: number) => void
Worker 对象的 onexit 属性表示 Worker 销毁时被调用的事件处理程序,处理程序在宿主线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
code | number | 否 | Worker 退出的 code。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.onexit = function (e) {
console.log("onexit");
};
2
3
4
# onerror
onerror?: (err: ErrorEvent) => void
Worker 对象的 onerror 属性表示 Worker 在执行过程中发生异常被调用的事件处理程序,处理程序在宿主线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
err | ErrorEvent | 否 | 异常数据。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.onerror = function (e) {
console.log("onerror");
};
2
3
4
# onmessage
onmessage?: (event: MessageEvent<T>) => void
Worker 对象的 onmessage 属性表示宿主线程接收到来自其创建的 Worker 通过 parentPort.postMessage 接口发送的消息时被调用的事件处理程序,处理程序在宿主线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
event | MessageEvent | 否 | 收到的 Worker 消息数据。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.onmessage = function (e) {
// e : MessageEvent<T>, 用法如下:
// let data = e.data;
console.log("onmessage");
};
2
3
4
5
6
# onmessageerror
onmessageerror?: (event: MessageEvent<T>) => void
Worker 对象的 onmessageerror 属性表示当 Worker 对象接收到一条无法被序列化的消息时被调用的事件处理程序,处理程序在宿主线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
event | MessageEvent | 否 | 异常数据。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.onmessageerror = function (e) {
console.log("onmessageerror");
};
2
3
4
# EventTarget
# addEventListener
addEventListener(type: string, listener: EventListener): void
向 Worker 添加一个事件监听。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | string | 是 | 监听的事件类型。 |
listener | EventListener | 是 | 回调的事件。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.addEventListener("alert", (e) => {
console.log("alert listener callback");
});
2
3
4
# removeEventListener
removeEventListener(type: string, callback?: EventListener): void
删除 Worker 的事件监听。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
type | string | 是 | 需要删除的监听事件类型。 |
callback | EventListener | 否 | 删除的回调事件。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.removeEventListener("alert");
2
# dispatchEvent
dispatchEvent(event: Event): boolean
分发定义在 Worker 的事件。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
event | Event | 是 | 需要分发的事件。 |
返回值:
类型 | 说明 |
---|---|
boolean | 分发的结果,false 表示分发失败。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.dispatchEvent({ type: "alert" });
2
# removeAllListener
removeAllListener(): void
删除 Worker 所有的事件监听。
系统能力: SystemCapability.Utils.Lang
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.removeAllListener();
2
# DedicatedWorkerGlobalScope
Worker 线程用于与宿主线程通信的类,通过 postMessage 接口发送消息给宿主线程、close 接口销毁 Worker 线程。DedicatedWorkerGlobalScope 类继承WorkerGlobalScope。
# postMessage
postMessage(messageObject: Object, options?: PostMessageOptions): void
Worker 线程向宿主线程发送消息。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
message | Object | 是 | 发送至宿主线程的数据。 |
options | PostMessageOptions | 否 | 可转移对象是 ArrayBuffer 的实例对象。transferList 数组中不可传入 null。 |
示例:
// main.js
import worker from "@ohos.worker";
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.postMessage("hello world");
workerInstance.onmessage = function (e) {
// let data = e.data;
console.log("receive data from worker.js");
};
2
3
4
5
6
7
8
// worker.js
import worker from "@ohos.worker";
const parentPort = worker.parentPort;
parentPort.onmessage = function (e) {
// let data = e.data;
parentPort.postMessage("receive data from main.js");
};
2
3
4
5
6
7
# close
close(): void
销毁 Worker 线程,终止 Worker 接收消息。
系统能力: SystemCapability.Utils.Lang
示例:
// main.js
import worker from "@ohos.worker";
const workerInstance = new worker.Worker("workers/worker.js");
2
3
// worker.js
import worker from "@ohos.worker";
const parentPort = worker.parentPort;
parentPort.onmessage = function (e) {
parentPort.close();
};
2
3
4
5
6
# onmessage
onmessage?: (event: MessageEvent<T>) => void
DedicatedWorkerGlobalScope 的 onmessage 属性表示 Worker 线程收到来自其宿主线程通过 postMessage 接口发送的消息时被调用的事件处理程序,处理程序在 Worker 线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
event | MessageEvent | 否 | 收到宿主线程发送的数据。 |
示例:
// main.js
import worker from "@ohos.worker";
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.postMessage("hello world");
2
3
4
// worker.js
import worker from "@ohos.worker";
const parentPort = worker.parentPort;
parentPort.onmessage = function (e) {
console.log("receive main.js message");
};
2
3
4
5
6
# onmessageerror
onmessageerror?: (event: MessageEvent<T>) => void
DedicatedWorkerGlobalScope 的 onmessageerror 属性表示当 Worker 对象接收到一条无法被反序列化的消息时被调用的事件处理程序,处理程序在 Worker 线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
event | MessageEvent | 否 | 异常数据。 |
示例:
// main.js
import worker from "@ohos.worker";
const workerInstance = new worker.Worker("workers/worker.js");
2
3
// worker.js
import worker from "@ohos.worker";
const parentPort = worker.parentPort;
parentPort.onmessageerror = function (e) {
console.log("worker.js onmessageerror");
};
2
3
4
5
6
# PostMessageOptions
明确数据传递过程中需要转移所有权对象的类,传递所有权的对象必须是 ArrayBuffer。
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
transfer | Object[] | 是 | 是 | ArrayBuffer 数组,用于传递所有权。 |
# Event
事件类。
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
type | string | 是 | 否 | 指定事件的类型。 |
timeStamp | number | 是 | 否 | 事件创建时的时间戳(精度为毫秒)。 |
# EventListener
(evt: Event): void | Promise<void>
事件监听类。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
evt | Event | 是 | 回调的事件类。 |
返回值:
类型 | 说明 |
---|---|
void | Promise<void> | 无返回值或者以 Promise 形式返回。 |
示例:
const workerInstance = new worker.Worker("workers/worker.js");
workerInstance.addEventListener("alert", (e) => {
console.log("alert listener callback");
});
2
3
4
# ErrorEvent
错误事件类,用于表示 Worker 执行过程中出现异常的详细信息,ErrorEvent 类继承Event。
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
message | string | 是 | 否 | 异常发生的错误信息。 |
filename | string | 是 | 否 | 出现异常所在的文件。 |
lineno | number | 是 | 否 | 异常所在的行数。 |
colno | number | 是 | 否 | 异常所在的列数。 |
error | Object | 是 | 否 | 异常类型。 |
# MessageEvent
消息类,持有 Worker 线程间传递的数据。
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
data | T | 是 | 否 | 线程间传递的数据。 |
# WorkerGlobalScope
Worker 线程自身的运行环境,WorkerGlobalScope 类继承EventTarget。
# 属性
系统能力: SystemCapability.Utils.Lang
名称 | 参数类型 | 可读 | 可写 | 说明 |
---|---|---|---|---|
name | string | 是 | 否 | Worker 的名字,new Worker 时指定。 |
self | WorkerGlobalScope & typeof globalThis | 是 | 否 | WorkerGlobalScope 本身。 |
# onerror
onerror?: (ev: ErrorEvent) => void
WorkerGlobalScope 的 onerror 属性表示 Worker 在执行过程中发生异常被调用的事件处理程序,处理程序在 Worker 线程中执行。
系统能力: SystemCapability.Utils.Lang
参数:
参数名 | 类型 | 必填 | 说明 |
---|---|---|---|
ev | ErrorEvent | 否 | 异常数据。 |
示例:
// main.js
import worker from "@ohos.worker";
const workerInstance = new worker.Worker("workers/worker.js");
2
3
// worker.js
import worker from "@ohos.worker";
const parentPort = worker.parentPort;
parentPort.onerror = function (e) {
console.log("worker.js onerror");
};
2
3
4
5
6
# 其他说明
# 序列化支持类型
Type | 备注 | 是否支持 |
---|---|---|
All Primitive Type | 不包括 symbol | 是 |
Date | 是 | |
String | 是 | |
RegExp | 是 | |
Array | 是 | |
Map | 是 | |
Set | 是 | |
Object | 只支持 Create from literal 的简单 Object,不支持带 function 的 | 是 |
ArrayBuffer | 提供 transfer 能力 | 是 |
TypedArray | 是 |
# 内存模型
Worker 基于 Actor 并发模型实现。在 Worker 的交互流程中,JS 主线程可以创建多个 Worker 子线程,各个 Worker 线程间相互隔离,并通过序列化传递对象,等到 Worker 线程完成计算任务,再把结果返回给主线程。
Actor 并发模型的交互原理:各个 Actor 并发地处理主线程任务,每个 Actor 内部都有一个消息队列及单线程执行模块,消息队列负责接收主线程及其他 Actor 的请求,单线程执行模块则负责串行地处理请求、向其他 Actor 发送请求以及创建新的 Actor。由于 Actor 采用的是异步方式,各个 Actor 之间相互隔离没有数据竞争,因此 Actor 可以高并发运行。
# 注意事项
- Worker 存在数量限制,当前支持最多同时存在 7 个 Worker。
- 当 Worker 数量超出限制,会出现 Error "Too many workers, the number of workers exceeds the maximum."。
- 主动销毁 Worker 可以调用新创建 Worker 对象的 terminate()或 parentPort.close()方法。
- Worker 的创建和销毁耗费性能,建议管理已创建的 Worker 并重复使用。
# 完整示例
# FA 模型
// main.js(同级目录为例)
import worker from "@ohos.worker";
// 主线程中创建Worker对象
const workerInstance = new worker.Worker("workers/worker.ts");
// 创建js和ts文件都可以
// const workerInstance = new worker.Worker("workers/worker.js");
// 主线程向worker线程传递信息
workerInstance.postMessage("123");
// 主线程接收worker线程信息
workerInstance.onmessage = function (e) {
// data:worker线程发送的信息
let data = e.data;
console.log("main.js onmessage");
// 销毁Worker对象
workerInstance.terminate();
};
// 在调用terminate后,执行回调onexit
workerInstance.onexit = function () {
console.log("main.js terminate");
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// worker.js
import worker from "@ohos.worker";
// 创建worker线程中与主线程通信的对象
const parentPort = worker.parentPort;
// worker线程接收主线程信息
parentPort.onmessage = function (e) {
// data:主线程发送的信息
let data = e.data;
console.log("worker.js onmessage");
// worker线程向主线程发送信息
parentPort.postMessage("123");
};
// worker线程发生error的回调
parentPort.onerror = function (e) {
console.log("worker.js onerror");
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
build-profile.json5 配置 :
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/MainAbility/workers/worker.ts"
]
}
}
2
3
4
5
6
7
# Stage 模型
// main.js(以不同目录为例)
import worker from "@ohos.worker";
// 主线程中创建Worker对象
const workerInstance = new worker.Worker("entry/ets/pages/workers/worker.ts");
// 创建js和ts文件都可以
// const workerInstance = new worker.Worker("entry/ets/pages/workers/worker.js");
// 主线程向worker线程传递信息
workerInstance.postMessage("123");
// 主线程接收worker线程信息
workerInstance.onmessage = function (e) {
// data:worker线程发送的信息
let data = e.data;
console.log("main.js onmessage");
// 销毁Worker对象
workerInstance.terminate();
};
// 在调用terminate后,执行onexit
workerInstance.onexit = function () {
console.log("main.js terminate");
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// worker.js
import worker from "@ohos.worker";
// 创建worker线程中与主线程通信的对象
const parentPort = worker.parentPort;
// worker线程接收主线程信息
parentPort.onmessage = function (e) {
// data:主线程发送的信息
let data = e.data;
console.log("worker.js onmessage");
// worker线程向主线程发送信息
parentPort.postMessage("123");
};
// worker线程发生error的回调
parentPort.onerror = function (e) {
console.log("worker.js onerror");
};
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
build-profile.json5 配置:
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/pages/workers/worker.ts"
]
}
}
2
3
4
5
6
7