小程序开发API之Worker线程

版权声明:欢迎转载,可Chat交流,写博不易请标明出处(钢丝球 M.Siebel): https://blog.csdn.net/JackJia2015/article/details/87972728

JavaScript 线程

JavaScript 语言采用的是单线程模型,也就是说,所有任务只能在一个线程上完成,一次只能做一件事。前面的任务没做完,后面的任务只能等着。随着电脑计算能力的增强,尤其是多核 CPU 的出现,单线程带来很大的不便,无法充分发挥计算机的计算能力。

Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

Worker 线程一旦新建成功,就会始终运行,不会被主线程上的活动(比如用户点击按钮、提交表单)打断。这样有利于随时响应主线程的通信。但是,这也造成了 Worker 比较耗费资源,不应该过度使用,而且一旦使用完毕,就应该关闭。

多线程 Worker

一些异步处理的任务,可以放置于 Worker 中运行,待运行结束后,再把结果返回到小程序主线程。Worker 运行于一个单独的全局上下文与线程中,不能直接调用主线程的方法。
Worker 与主线程之间的数据传输,双方使用Worker.postMessage() 来发送数据,Worker.onMessage()来接收数据,传输的数据并不是直接共享,而是被复制的。

使用流程

1. 配置 Worker 信息

在 app.json 中可配置 Worker 代码放置的目录,目录下的代码将被打包成一个文件:
配置示例:
{
“workers”: “workers”
}

2. 添加 Worker 代码文件

根据步骤 1 中的配置,在代码目录下新建以下两个入口文件:
workers/request/index.js
workers/request/utils.js
workers/response/index.js

添加后,目录结构如下:
├── app.js
├── app.json
├── project.config.json
└── workers
  ├── request
  │ ├── index.js
  │ └── utils.js
  └── response
   └── index.js

3. 编写 Worker 代码

workers/request/index.js编写 Worker 响应代码

const utils = require('./utils')

// 在 Worker 线程执行上下文会全局暴露一个 worker 对象,直接调用 worker.onMeesage/postMessage 即可
worker.onMessage(function (res) {
  console.log(res)
})


4. 在主线程中初始化 Worker

在主线程的代码 app.js 中初始化 Worker
const worker = wx.createWorker(‘workers/request/index.js’) // 文件名指定 worker 的入口文件路径,绝对路径

5. 主线程向 Worker 发送消息

worker.postMessage({
msg: ‘hello worker’
})

注意事项

  1. Worker 最大并发数量限制为 1 个,创建下一个前请用 Worker.terminate() 结束当前 Worker
  2. Worker 内代码只能 require 指定 Worker 路径内的文件,无法引用其它路径
  3. Worker 的入口文件由 wx.createWorker() 时指定,开发者可动态指定 Worker 入口文件
  4. Worker 内不支持 wx 系列的 API
  5. Workers 之间不支持发送消息

Worker线程API

wx.createWorker(string scriptPath)

创建一个 Worker 线程。目前限制最多只能创建一个 Worker,创建下一个 Worker 前请先调用 Worker.terminate

参数

string scriptPath worker 入口文件的绝对路径
返回值
Worker 对象

Worker

Worker 实例,主线程中可通过 wx.createWorker 接口获取,worker 线程中可通过全局变量 worker 获取。

方法

Worker.postMessage(Object message)
向主线程/Worker 线程发送的消息。
function callback
主线程/Worker 线程向当前线程发送的消息的事件的回调函数
参数 Object res在这里插入图片描述

Worker.terminate()
结束当前 Worker 线程。仅限在主线程 worker 对象上调用。
示例代码
运行以下代码需先进行基础配置,详细请查阅 多线程 文档了解基础知识和配置方法。

const worker = wx.createWorker('workers/request/index.js') // 文件名指定 worker 的入口文件路径,绝对路径

worker.onMessage(function (res) {
  console.log(res)
})

worker.postMessage({
  msg: 'hello worker'
})

worker.terminate()

Worker.onMessage(function callback)
监听主线程/Worker 线程向当前线程发送的消息的事件。
Object message
需要发送的消息,必须是一个可序列化的 JavaScript key-value 形式的对象。
示例代码
worker 线程中

worker.postMessage({
  msg: 'hello from worker'
})

主线程中

const worker = wx.createWorker('workers/request/index.js')

worker.postMessage({
  msg: 'hello from main'
})

示例代码

workers/request/index.js

const utils = require('./utils')

console.log('hello worker')

worker.postMessage({
  msg: 'hello from worker: ' + utils.test(),
  buffer: utils.str2ab('hello arrayBuffer from worker')
})

worker.onMessage((msg) => {
  console.log('[Worker] on appservice message', msg)
  const buffer = msg.buffer
  console.log('[Worker] on appservice buffer length ', buffer)
  console.log('[Worker] on appservice buffer', utils.ab2str(buffer))
})

workers/request/utils.js

function test() {
  return 1 + 1
}

function ab2str(buf) {
  return String.fromCharCode.apply(null, new Uint16Array(buf));
}

function str2ab(str) {
  var buf = new ArrayBuffer(str.length * 2); // 2 bytes for each char
  var bufView = new Uint16Array(buf);
  for (var i = 0, strLen = str.length; i < strLen; i++) {
    bufView[i] = str.charCodeAt(i);
  }
  return buf;
}

module.exports = {
  test: test,
  ab2str: ab2str,
  str2ab: str2ab
}





猜你喜欢

转载自blog.csdn.net/JackJia2015/article/details/87972728