基于MessageChannel或postmessage实现通信

320 阅读1分钟

概念及使用

postmessage

MessageChannel

实现窗口之间通讯

MessageChannel

// 窗口A:
const iframe = document.getElementById('windowB');

const btn = document.getElementById('btn');

const channel = new MessageChannel();

iframe.addEventListener('load', () => {

    // 监听从 iframe 返回的消息
    channel.port1.onmessage = function(event) {
        console.log('😊😊😊😊😊😊Received message from windowB:', event.data);
    };

    // 将 port1 发送给 iframe
    iframe.contentWindow.postMessage('hello windowB', '*', [channel.port2]);

    btn.onclick = () => {
        channel.port1.postMessage(Math.random() * 10000000);
    }
})
// 窗口B:
let portRef = null;

window.addEventListener('message', function (event) {
    // 这条是通过postmessage实现的通信
    console.log('😊😊😊😊😊😊😊Received message from Window A:', event.data);

    const [port] = event.ports;

    if (!portRef) {
        portRef = port;

        portRef.onmessage = (event) => {
            console.log('Received message from Window A', event.data)
        }

    }

    // 通过 port 发送消息回父窗口
    portRef.postMessage('hello window A');

});

postMessage

// windwoA
iframe1 = document.getElementById('windwoB');

window.addEventListener('message', (e) => {

    if (e.origin !== 'http://127.0.0.1:5500') {
        return;
    }

    console.log('receive from window B', e.data);

});

iframe1.addEventListener('load', () => {

    iframe1.contentWindow.postMessage("hello window B", 'http://127.0.0.1:5500/');
 
});
// window B
window.addEventListener('message', (e) => {

    if (e.origin === 'http://127.0.0.1:5500') {

        console.log('receive from window A', e.data)

        e.source.postMessage('hello window A')

    }

});

实现主线程和worker之间通信

MessageChannel

const worker = new Worker('./workerByMessage.js');

const channel = new MessageChannel();

worker.postMessage({ type: "connect" }, [channel.port2]);

channel.port1.onmessage = function (evt) {

    console.log(evt.data);
    
}
// workerByMessage.js

self.addEventListener('message', (evt) => {

    const channel = new MessageChannel();

    evt.ports[0].postMessage({ data: 'response' }, [channel.port2]);

    channel.port1.onmessage = function (evt) {

        console.log(evt.data);

    }

    console.log(evt.data, '===');

})

postMessage

const worker = new Worker('./worker.js');

const data = {

    name: 'John Doe',
    age: 30,
    address: {
        street: '123 Main St',
        city: 'Anytown',
        state: 'CA'
    },
    hobbies: ['reading', 'hiking', 'cooking']
};

worker.postMessage(JSON.stringify(data));

// 接收 Web Worker 发送的消息
worker.addEventListener('message', (event) => {

    const result = JSON.parse(event.data);

    console.log('Received result from Worker:', result);

});
// worker.js
self.addEventListener('message', (e) => {

    const data = JSON.parse(e.data);

    console.log('Received data from Main Thread:', data);

    // 处理数据并返回结果
    const result = {
        fullName: `${data.name}`,
        age: data.age,
        address: `${data.address.street}, ${data.address.city}, ${data.address.state}`
    };

    // 向主线程发送结果
    self.postMessage(JSON.stringify(result));
});