JS:MessageChannel

MessageChannel API

MessageChannel 为通信管道对象,使用 MessageChannel 构造函数将返回一个 MessageChannel 对象,返回的对象中包含两个 MessagePort 对象,可以实现双端通信。
MessageChannel的onmessage回调属于宏任务。

// 创建 MessageChannel 新实例对象
var channel = new MessageChannel();

// MessageChannel实例默认具有port1和port2两个对象属性
var port1 = channel.port1;
var port2 = channel.port2;

// MessageChannel实例onmessage事件可以实现监听并绑定回调函数
port1.onmessage = function(event) {
    console.log("port1收到来自port2的数据:" + event.data);
}
port2.onmessage = function(event) {
    console.log("port2收到来自port1的数据:" + event.data);
}

// MessageChannel实例postMessage方法可以触发onmessage事件
port1.postMessage("发送给port2");
port2.postMessage("发送给port1");

MessageChannel 结合 Web Worker 可以实现多线程通信:

// main.js
let worker1 = new Worker('./worker1.js');
let worker2 = new Worker('./worker2.js');
let ms = new MessageChannel();

// 把 port1 分配给 worker1
worker1.postMessage({ name: 'port', port: ms.port1 }, [ms.port1]);
// 把 port2 分配给 worker2
worker2.postMessage({ name: 'port', port: ms.port2}, [ms.port2]);

以上代码把消息通道的 port1 和 port2 分别分配给了 worker1和 worker2,即用消息通道将两个 worker 给连接起来。

关于 postMessage
Web Worker 的 postMessage 方法 可接收两个参数:
message: 消息内容,可以是任意基础数据类型或ArrayBuffer、MessageChannel、ImageBitmap等实例对象
transferList: 可选,包含被传输对象的数组,数组中的对象的所有权会转移给当前调用postMessage 方法 的Web Worker

// worker1.js
self.onmessage = function(e) {
    if (e.data.name === 'port') {
        const port = e.data.port;
        port.postMessage("Hi! I'm worker1");
    }       
}
// worker2.js
self.onmessage = function(e) {
	if (e.data.name === 'port') {
        const port = e.data.port;
      	port.onmessage = function(event) {
             console.log(event.data);
        }
    } 
}

代码运行时,worker1 中通过 port1 发送消息,然后 worker2 就能从 port2 中接收到消息。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在 Android 中,MessageChannel 是一种通过 WebView 实现 JavaScript 和 Native 之间双向通信的机制。使用 MessageChannel,我们可以在 JavaScript 和 Native 之间传递消息和数据。MessageChannel 可以传递基本数据类型(如字符串、整数、布尔值等),也可以传递对象。 使用 MessageChannel 传递对象的步骤如下: 1. 在 Native 中创建一个 MessageChannel,并将其注册到 WebView 中: ```java // 创建 MessageChannel MessageChannel channel = new MessageChannel(); // 将 channel.port1 注入到 WebView 中 webView.addJavascriptInterface(new MyJavaScriptInterface(channel.port1), "MyJavaScriptInterface"); ``` 在这个例子中,我们创建了一个 MessageChannel,并将其注册到 WebView 中。我们也创建了一个名为 "MyJavaScriptInterface" 的 JavaScript 接口,并将 channel.port1 注入到该接口中。这样,JavaScript 就可以通过 "MyJavaScriptInterface" 对象来访问 channel.port1。 2. 在 JavaScript 中创建一个 MessageChannel,并将其与 Native 中的 channel.port2 相关联: ```javascript // 创建 MessageChannel var channel = new MessageChannel(); // 发送 channel.port2 到 Native 端 window.MyJavaScriptInterface.postMessage(channel.port2, [channel.port2]); ``` 在这个例子中,我们创建了一个 MessageChannel,并将其与 Native 中的 channel.port2 相关联。我们也使用 window.MyJavaScriptInterface.postMessage() 方法将 channel.port2 发送到 Native 端。 3. 在 Native 中接收 JavaScript 发送的数据: ```java class MyJavaScriptInterface { private MessagePort port; public MyJavaScriptInterface(MessagePort port) { this.port = port; this.port.setWebContentsDebuggingEnabled(true); this.port.setDelegate(new MessagePort.Delegate() { @Override public void onMessagePortMessage(MessagePort messagePort, MessagePort.MessageEvent messageEvent) { // 处理 JavaScript 发送的数据 Object data = messageEvent.getData(); // ... } }); } } ``` 在这个例子中,我们创建了一个名为 MyJavaScriptInterface 的 Java 类,并在构造函数中设置了 MessagePort 的回调函数。当 JavaScript 发送数据到 Native 端时,该回调函数会被触发,并且我们可以在该函数中处理 JavaScript 发送的数据。 需要注意的是,由于 MessageChannel 是跨线程的,因此需要使用 Handler 或者 AsyncTask 等机制来确保数据的同步和安全性。此外,在传递对象时,需要确保对象是可序列化的。如果对象无法序列化,则需要将其转换为可序列化的格式(如 JSON 对象等),然后再传递。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值