zoukankan      html  css  js  c++  java
  • MessageChannel用法总结

    MessageChannel,顾名思义,通信管道,可以实现两端的通信。

    基本用法:

    var channel = new MessageChannel();
    var port1 = channel.port1;
    var port2 = channel.port2;
    port1.onmessage = function(event) {
        console.log("port1收到来自port2的数据:" + event.data);
    }
    port2.onmessage = function(event) {
        console.log("port2收到来自port1的数据:" + event.data);
    }
    
    port1.postMessage("发送给port2");
    port2.postMessage("发送给port1");

    1. web worker兄弟线程通信

    let worker1 = new Worker('./worker1.js');
    let worker2 = new Worker('./worker2.js');
    let ms = new MessageChannel();
    
    // 把 port1 分配给 worker1
    worker1.postMessage('main', [ms.port1]);
    // 把 port2 分配给 worker2
    worker2.postMessage('main', [ms.port2]);
    
    //worker1.js
    self.onmessage = function(e) {
        console.log('worker1', e.ports);
        if (e.data === 'main') {
            const port = e.ports[0];
            port.postMessage(`worker1: Hi! I'm worker1`);
            port.onmessage = function(ev){
                console.log('reveice: ',ev.data,ev.origin);
            }
        }       
    }
    
    //worker2.js
    self.onmessage = function(e) {
        if (e.data === 'main') {
            const port = e.ports[0];
            port.onmessage = function(e) {
                console.log('receive: ', e.data);
                port.postMessage('worker2: ' + e.data);
            }
        }
    }

    2. iframe兄弟通信

    //主页面
    <iframe id="iframe1" src="./iframe1.html"></iframe>
    <iframe id="iframe2" src="./iframe2.html"></iframe>
    <script>
        window.onload = function(){
            var {port1,port2} = new MessageChannel();
            var iframe1 = document.getElementById('iframe1');
            iframe1.contentWindow.postMessage('main','*',[port1]);
            var iframe2 = document.getElementById('iframe2');
            iframe2.contentWindow.postMessage('main','*',[port2]);
        }
    </script>
    
    //iframe1
    <div id="message"></div>
    <script>
        window.addEventListener('message',function(event){
            console.log(event);
            let messageDom = document.getElementById('message');
            messageDom.innerHTML = "收到"  + event.origin + "消息:" + event.data;
    
            let port = event.ports[0];
            port.onmessage = function(e){
                messageDom.innerHTML += '<br/>收到' + e.origin + '消息: ' + e.data;
            }
            port.postMessage('from iframe1');
      }, false);
    </script>
    
    //iframe2
    <div id="message"></div>
    <script>
        window.addEventListener('message',function(event){
            console.log(event);
            let messageDom = document.getElementById('message');
            messageDom.innerHTML = "收到"  + event.origin + "消息:" + event.data;
    
            let port = event.ports[0];
            port.onmessage = function(e){
                messageDom.innerHTML += '<br/>收到' + e.origin + '消息: ' + e.data;
            }
            port.postMessage('from iframe2');
        }, false);
    </script>

    3. worker_threads兄弟线程通信

    nodejs的MessageChannel虽然与浏览器的,实现方式不同,但是用法相同,都是一个模型。在此列出,阐释这种思想。

    //index.js
    const {isMainThread, parentPort, threadId, MessageChannel, Worker} = require('worker_threads');
       
    if (isMainThread) {
        //__filename是指worker1会走下面的else分支
        //node使用isMainThread来判断走的是主线程还是worker线程
        //这样worker线程的代码可以和主线程写在一个文件中
        const worker1 = createWorker(__filename);
        const worker2 = createWorker('./worker2.js');
        const {port1,port2} = new MessageChannel();
        worker1.postMessage({ port1 }, [port1]);
        worker2.postMessage({ port2 }, [port2]);
    } 
    else {
        //worker1
        parentPort.once('message', ({port1}) => {
            port1.postMessage('hello');
            port1.on('message', msg => {
                console.log(`thread ${threadId}: receive ${msg}`);
            });
        });
    }
    
    function createWorker(filaPath){
        const worker = new Worker(filaPath);
        worker.on('exit', code => { console.log(`main: worker stopped with exit code ${code}`); });
        worker.on('message', msg => {
            console.log(`main: receive ${msg}`);
            worker.postMessage(msg + 1);
        });
        return worker;
    }
    
    //worker2.js
    const {parentPort,threadId} = require('worker_threads');
    
    parentPort.on('message',({port2}) => {
        port2.postMessage('form worker2');
        port2.on('message',(msg) => {
            console.log(`thread ${threadId}: receive ${msg}`);
        })
    })
  • 相关阅读:
    python 复杂一点的装饰器
    python 装饰器
    python 歌词解析
    ATX 免越狱调试IOS和Android
    OpenCV库文件介绍
    NetEaseGame/ATX 的MD
    带你玩转Visual Studio——带你高效开发
    python 图像识别
    fatal: Authentication failed for又不弹出用户名和密码 解决办法
    lua luna工具库
  • 原文地址:https://www.cnblogs.com/mengff/p/12818522.html
Copyright © 2011-2022 走看看