【JS】postMessage与MessageChannel

news2024/9/20 6:08:51

前言

postMessageMessageChannel 都是用来实现跨文档跨窗口跨线程(Web Worker)的消息传递机制。

postMessage

可以在 iframe、同源或跨源窗口之间传递数据,也可以用于主线程与 Web Worker 之间的通信。

postMessage 是一种单向的消息传递机制,适用于同源或跨域窗口之间的通信。可以用它来向一个窗口发送消息,而这个窗口通过监听 message 事件来接收消息。通常用于主页面和 iframe 或主线程和 Web Worker 之间的通信。

// 在主线程中创建 Web Worker
const worker = new Worker('worker.js');

// 发送消息到 Worker
worker.postMessage({ type: 'INIT', data: 'Hello!' });

// 在 Worker 中监听消息
self.addEventListener('message', (event) => {
  console.log('监听到的消息:', event.data);
  // 发送响应回主线程
  self.postMessage('你好!');
});

// 在主线程中监听 Worker 的响应
worker.addEventListener('message', (event) => {
  console.log('监听到的消息:', event.data);
});

postMessage实现iframe跨域通信请看本人另一篇文章:postMessage实现iframe跨域通信

MessageChannel

MessageChannel 创建两个 MessagePort 对象,这两个端口可以通过 postMessage 相互通信。它比 postMessage 更灵活,适用于需要复杂双向通信的场景。

// 创建一个 MessageChannel 实例
const channel = new MessageChannel();

// 获取两个端口
const port1 = channel.port1;
const port2 = channel.port2;

// 监听 port1 上的消息
port1.onmessage = (event) => {
  console.log('接收到的消息:', event.data);
};

// 向 port2 发送消息
port2.postMessage('port2发送的消息');

可以在不同的上下文中使用 postMessage 传递 port2 或 port1

file1.js

const channel = new MessageChannel();

// 监听来自 port1 的消息
channel.port1.onmessage = (event) => {
  console.log("接收到的消息:", event.data);
};

// 将 port2 传递给目标文件(iframe 或 Web Worker)
const iframe = document.querySelector('iframe');
iframe.contentWindow.postMessage('Sending port', '*', [channel.port2]);

// 向 port1 发送一条消息
channel.port1.postMessage("你好,我是file1的消息");

file2.js

// 监听来自主页面的消息
window.addEventListener('message', (event) => {
  // 检查是否收到了 MessageChannel 的 port
  if (event.data === 'Sending port' && event.ports.length > 0) {
    const port2 = event.ports[0];

    // 监听 port2 上的消息
    port2.onmessage = (event) => {
      console.log("监听到的消息:", event.data);

      // 回应 port1 的消息
      port2.postMessage("我是file2的消息");
    };
  }
});

React 调度器 Scheduler 源码也有用到 MessageChannel,根据可用的 API 选择最合适的调度方法。

  • Node.js 环境中,优先使用 setImmediate,它的执行时间更早,并且不会阻止 Node.js 进程退出。
  • MessageChannel 有时可能导致 Node.js 进程延迟退出。在浏览器环境中,比 setTimeout 更精确地控制任务执行时间(更少的时间颗粒度)。例如,setTimeout 可能会有最低延迟限制(如 4 毫秒),而 MessageChannel 可以更快地触发任务。
  • localSetTimeout: 标准的 setTimeout 函数,如果在环境中既没有 setImmediate 也没有 MessageChannel,那么使用 setTimeout 作为最后的回退方案。通常是在非浏览器环境中,比如一些测试环境或非常旧的环境中。

在这里插入图片描述

总结

postMessageMessageChannel
是否支持跨域
通信方式单向通信双向通信
消息数据可以传递基本数据类型和结构化克隆的数据(如对象、数组、文件等),但不能直接传递上下文(如函数)不仅可以传递数据,还可以通过 postMessage 传递 MessagePort,从而创建多个通信通道
优势简单快捷适用于较复杂的双向通信

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2148189.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Django 聚合查询

文章目录 一、聚合查询二、使用步骤1.准备工作2.具体使用3.分组查询(annotate)1.定义2.使用3.具体案例 4.F() 查询1.定义2.使用 5.Q() 查询1.定义2.查询 一、聚合查询 使用聚合查询前要先从 django.db.models 引入 Avg、Max、Min、Count、Sum&#xff0…

VS code EXPLORER 中不显示指定文件及文件夹设置(如.pyc, __pycache__, .vscode 文件)

VS code EXPLORER 中不显示指定文件及文件夹设置 引言正文方法1打开方式1打开方式2 方法2 引言 VS code 号称地表最强轻量级编译器,其最大的优势在于用户可以根据自己的需求下载适合自己的 extension。从而定制个性化的编译器。然而,本人今天遇到了一个…

如何调用API接口:一份简明指南

在软件开发中,调用API接口是一项基本而重要的技能。API(应用程序编程接口)允许不同程序之间进行交互,使得数据和功能可以跨应用程序共享。本文将为你提供一份简明的指南,帮助你理解如何调用API接口。 什么是API接口&am…

Android中的引用类型:Weak Reference, Soft Reference, Phantom Reference 和 WeakHashMap

在Android开发中,内存管理是一个非常重要的话题。为了更好地管理内存,Java和Android提供了多种引用类型,包括Weak Reference、Soft Reference、Phantom Reference以及WeakHashMap。这些引用类型在不同的场景下可以帮助我们更有效地管理内存&a…

(笔记)mac笔记本调节键盘速率

我在使用neovim的时候,发现按下hjkl或者shift[]来进行移动的时候 开始延迟大概几百毫秒的时间才开始移动 所以我上网找了下方法 发现修改这了可以改变速率 我就直接拉到了fast 芜湖 起飞 local opt vim.opt local o vim.o local g vim.go.timeoutlen 100 o…

论文速递!时序预测!DCSDNet:双卷积季节性分解网络,应用于天然气消费预测过程

本期推文将介绍一种新的时序预测方法:双卷积季节性分解网络(Dual Convolution withSeasonal Decomposition Network, DCSDNet)在天然气消费预测的应用,这项研究发表于《Applied Energy》期刊。 针对天然气消费的多重季节性和非规律性&#x…

汽车焊机数据通信:Profinet转Canopen网关的神奇连接

在汽车制造领域,汽车焊机的高效、稳定运行对于整车质量至关重要。而Profinet转Canopen网关在汽车焊机的数据通信中发挥着关键作用。 Profinet是一种广泛应用于工业自动化领域的通信协议,具有高速、实时、可靠等特点。Canopen则在汽车电子等领域有着广泛…

软件渗透测试流程有哪些?专业软件测评公司简析渗透测试的好处

软件渗透测试是进行软件安全测评的重要环节,旨在通过模拟攻击手段发现软件系统的脆弱性。这种安全测试方法能够帮助开发人员和系统管理员发现并修复潜在的安全漏洞,以确保软件系统的安全性和完整性。软件渗透测试是一项高度技术性的任务,需要…

口哨声、歌声、boing声和biotwang声:用AI识别鲸鱼叫声

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗?订阅我们的简报,深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同,从行业内部的深度分析和实用指南中受益。不要错过这个机会,成为AI领…

算法打卡 Day41(动态规划)-理论基础 + 斐波那契数 + 爬楼梯 + 使用最小花费爬楼梯

文章目录 理论基础Leetcode 509-斐波那契数题目描述解题思路 Leetcode 70-爬楼梯题目描述解题思路 Leetcode 746-用最小花费爬楼梯题目描述解题思路 理论基础 动态规划,简称 DP,其中的每一个状态一定是由上一个状态推导出来的,而贪心算法没有…

Mastering Qt 番外 —— 添加源码调试

笔者最近正在尝试深入的学习Qt框架,经常需要明确我经常使用的类底下发生了什么,因此笔者决定仔细研究一下如何进行源码级别的调试 此篇文章将会介绍如何使用Qt Creator这个IDE进行调试。最终效果如下 EasyWay 笔者采用的是这个最简单明了的方式&#xff…

回归预测|基于鹈鹕优化径向基神经网络的数据回归预测Matlab程序POA-RBF 多特征输入单输出 含基础RBF

回归预测|基于鹈鹕优化径向基神经网络的数据回归预测Matlab程序POA-RBF 多特征输入单输出 含基础RBF 文章目录 一、基本原理1. **饥饿游戏搜索优化算法(POA)简介**2. **径向基神经网络(RBF)简介**3. **POA-RBF回归预测流程**1. **…

重修设计模式-设计原则

重修设计模式-设计原则 设计原则 设计原则是软件编码时所遵循的规则,旨在帮助开发者创建出既满足功能需求又易于维护、可扩展且美观的设计,理解设计原则可以提升代码质量、减少错误以及促进团队协作,但对设计原则的理解要灵活,不…

前端vue-父传子

父传子的话是在components中创建一个子组件MyTest.vue&#xff0c;并且在父组件中先导入(import MyTest from "./components/MyTest")&#xff0c;再注册&#xff08;在expo二default中写上 compnents:{MyTest}&#xff09;&#xff0c;再使用标签&#xff08;<My…

深度学习后门攻击分析与实现(一)

在计算机安全中&#xff0c;后门攻击是一种恶意软件攻击方式,攻击者通过在系统、应用程序或设备中植入未经授权的访问点,从而绕过正常的身份验证机制,获得对系统的隐蔽访问权限。这种"后门"允许攻击者在不被检测的情况下进入系统,执行各种恶意活动。 后门可以分为几种…

开源项目 GAN 漫画风格化 UGATIT

开源项目&#xff1a;DataBall / UGATIT GitCode * 数据集 * [该项目制作的训练集的数据集下载地址(百度网盘 Password: gxl1 )](https://pan.baidu.com/s/1683TRcv3r3o7jSitq3VyYA) * 预训练模型 * [预训练模型下载地址(百度网盘 Password: khbg )](https://pan.ba…

安卓实现导入Excel文件

使用简化版的jar包 api files(libs/poi-3.12-android-a.jar) api files(libs/poi-ooxml-schemas-3.12-a.jar) 导入遇到了两个兼容问题 1.build.gradle文件里面 android { 要添加 packagingOptions {exclude META-INF/INDEX.LIST } 2.加载大文件要在清单文件里面加androi…

2023年全国研究生数学建模竞赛华为杯B题DFT类矩阵的整数分解逼近求解全过程文档及程序

2023年全国研究生数学建模竞赛华为杯 B题 DFT类矩阵的整数分解逼近 原题再现&#xff1a; 一、问题背景   离散傅里叶变换&#xff08;Discrete Fourier Transform&#xff0c;DFT&#xff09;作为一种基本工具广泛应用于工程、科学以及数学领域。例如&#xff0c;通信信号…

YOLO交通目标识别数据集(红绿灯-汽车-自行车-卡车等)

YOLO交通目标识别 数据集 模型 ui界面 ✓图片数量15000&#xff0c;xml和txt标签都有&#xff1b; ✓class&#xff1a;biker&#xff0c;car&#xff0c;pedestrian&#xff0c;trafficLight&#xff0c;trafficLight-Green&#xff0c;trafficLight-GreenLeft&#xff0c; t…

java se 快速入门

文章目录 java se 快速入门Java 简介Java的优点jdk 和 jre安装jdk配置环境变量Java 语法快速入门程序入口文件名类规范 基本语法注释变量和常量输入输出条件语句循环语句 基本数据类型Java字符串常用方法字符串拼接java字节数组和字符串相互转化java字符数组和字符串相互转换ja…