BroadcastChannel

BroadcastChannel

BroadcastChannel 允许同源脚本跨 window / tabiframeweb worker 进行多对多通信

API

BroadcastChannel 构造函数只接受参数,那就是广播名称(channel name)

1
const channel = new BroadcastChannel('name');

BroadcastChannel 接口定义如下:

1
2
3
4
5
6
7
8
[Constructor(DOMString name), Exposed=(Window,Worker)]
interface BroadcastChannel : EventTarget {
readonly attribute DOMString name;
void postMessage(any message);
void close();
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
};
  • name:频道名称,用来区分不同频道(跨频道不可通信)
  • postMessage:广播频道信息
  • onmessage:接受广播信息
  • close:停止接受频道信息

通信过程

每个页面创建相同频道名称的 BraodcastChannel 对象并进入频道,通过 onmessage 来接受频道广播的信息,通过 postMessage() 方法可以广播信息给所有加入当前频道的页面。

本质上,这是在特定频道下的全双工(双向)通信,每个页面都可以在频道中彼此收发任何消息。不可跨频道通信

BroadcastChannel 对象的 close() 只是调用者自己停止接受广播信息,不影响其它页面。

还有一点需要注意的事,消息事件中传输的对象并不是深拷贝,传输的是对象的引用地址

1
2
3
4
5
6
7
8
9
10
// page A
const a = new BroadcastChannel('app');
const list = ['A', 'B'];
a.postMessage({ list });

// page B
const b = new BroadcastChannel('app')
b.onmessage = function (event) {
event.data.list.push('C')
}

对比

目前除了 BroadcastChannel 外,有好几种信息发送技术,如 WebSocketsSharedWorkerMessageChannelwindow.postMessage()。不同的技术,适合不同的场景,下面简单的对比下。

  • BroadcastChannel vs postMessage()

    • 前者必须在同域传输,后者允许跨域传输数据
    • 前者传输的是对象引用地址,后者传输的是经过 structured clone algorithm 后的数据
  • BroadcastChannel vs SharedWorker()

    • 前者只是简单的在多个页面或 worker 之间进行数据传输,后者在服务器与客户端之间的状态管理、资源同步方面更具优势
  • BroadcastChannel vs MessagChannel

    • 两者之间最大的区别在于前者是多对多通讯,后者是一对一通讯

polyfills

参考