本文原创发布在华为开发者社区。
介绍
TaskPool和Worker均支持多线程并发能力。
- TaskPool的工作线程会绑定系统的调度优先级,并且支持负载均衡(自动扩缩容);
- Worker需要开发者自行创建,存在创建耗时以及不支持设置调度优先级;
- 性能方面使用TaskPool会优于Worker,因此大多数场景推荐使用TaskPool。
本示例分别利用TaskPool和Worker开发多线程并发场景,以此来展示两者的不同之处以及相似之处。
实现多线程并发功能源码链接
效果预览

使用说明
- 进入应用会看到消息列表,消息实时刷新。
- 点击任一消息进入对话框,点击下载按钮可将文件下载保存到本地。
实现思路
- aboutToAppear,在组件即将出现时被调用,用于执行初始化、数据准备操作。
- workerInstance.postMessage,向workerInstance发送一条消息,消息是一个对象,包含type属性设置为true和context属性设置为this.context。使用postMessage方法将消息发送给Web Worker,用于开启子线程任务,并且可以根据业务需求传递自定义的上下文信息。
- workerInstance.onmessage ,workerInstance注册一个消息处理函数,当从子线程接收到消息时会调用该函数。
- let newMessage: string = e.data.toString();:将接收到的数据(e.data)转换为字符串类型,并存储在 newMessage 变量中。
- 在每个页面点击下载后,执行以下操作:
-
创建一个taskpool.Task对象task,将downloadFile函数作为任务,使用this.params.name 作为任务名称,指定一个文件的下载链接,并传入this.context作为任务的上下文。
-
为emitter对象注册event事件的监听器,在事件触发时,从eventData中提取progress信息。
-
打印下载进度信息到控制台。
-
当进度达到 100 时,使用 promptAction.showToast 显示一个下载完成的提示,位置在底部 100 像素处。
这里使用了TaskPool方式,这种方式偏向独立任务维度,该任务在线程中执行,无需关注线程的生命周期,超长任务(大于3分钟)会被系统自动回收。
- 构造messageReceive()函数,调用systemDateTime.getCurrentTime()方法获取当前时间,使用await等待结果并存储在time变量中。将获取到的当前时间打印到控制台。检查time是否是5000的倍数,如果是,则返回一个字符串name-${time},否则返回一个空字符串。
- 为workerPort的onmessage事件添加一个异步处理函数,当接收到消息时会执行以下操作:
-
打印execute worker task到控制台。
-
从e.data.type中获取flag并将其转换为布尔类型,用于控制while循环。
-
当flag为true时,进入while循环。
-
在循环中调用messageReceive函数获取消息,并使用await等待结果。
-
如果receiveMessage不为空,打印消息并使用workerPort.postMessage将消息发送回宿主线程。
这里使用了Worker方式,这种方式偏向线程的维度,支持长时间占据线程执行,需要主动管理线程生命周期。