• 利用 postMessage 进行数据传递 (iframe 及web worker)及问题


    一 postMessage应用于主页面和iframe之间进行数据的传递

    1  子iframe页面向主页面进行数据传递;

    // 多个子iframe需要将自己的计数统计到主页面进行数据上报
    window.parent.postMessage({
        count:count(),
        id:'1'
    },'*');
    // 主页面进行接收
    window.onmessage = (e)=>{
        if(!e.data.id) return;
        var id = e.data.id;
        var count = e.data.count;
        // 根据收到的子页面的数据进行更新的操作 通过id判断具体是哪个页面
        updateCountMessage(id,count);
    };
    

    2  主页面向子页面进行数据的下发,比如需要将初始计数的数据分发到各个iframe

    // 给各个iframe添加加载事件 以vue框架为例
    // template
    <iframe :ref="item.id" @load="loadandpostmessage" :data-id="item.id" :data.init="item.init">
    
    // script
    loadandpostmessage(event) {
        event.target.contentWindow.postMessage({
            id: event.target.dataset.id,
            init: event.target.dataset.init,
            oper: 'whole'
        },'*');
    }
    // 可以根据列表的某一项分别的更新数据
    opener(item){
        this.$refs[vm.curId][0].contentWindow.postMessage({
            id:item.id,
            init: item.init,
            oper: 'seperate'
        },'*');
    }
    // 子页面进行数据的接收 ,可以同时对多个信息进行接收 ,只是需要不同的标记进行区别
    window.onmessage = function(e){
        if(!e.data.id) return;
        if(e.data.oper=='whole'){
           console.log('方式1接收到多个消息')
        }else{
           console.log('方式2接收到单独的主页面消息');
        }
        
    };
    

    注意:

      1 当使用webpack时 webpack自身会发送postMessage,注意监听message时区分具体是自己发来的message还是webpackOK ;

      2 Q :在本地开启静态服务器(利用lite-server)时,在主页面和多个iframe页面之间数据传递调用相应的函数,会存在在不同的iframe页面内同一函数都被执行了的问题;

       A: lite-server开启的静态服务器共享了实例导致不同页面的同一个函数都被执行,我们换一个server既可,如使用vs打开 之后选择要运行的文件在右下角功能栏最左侧有Go Live 既可在浏览器中打开页面

           

    二 postMessage应用于js主线程和worker多线程之间进行数据传递,下面对比原生和webworker的不同

    html文件内容

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
        <div class="main-wrap"></div>
        <div class="method">原生js获取获取数列第40项</div>
    </body>
    <script>
        document.querySelector('.method').onclick = function(event){
            console.log('hello world');
        }
        function fibonacci(n){
            return n<2?n:arguments.callee(n-1)+arguments.callee(n-2);
        }
        console.log('原生js获取'+fibonacci(40));
    
        
        // 利用worker 可以实现js的异步调用 这样避免了js文件因为数据等问题造成的页面的卡顿假死的现象;
        // var myWorker = new Worker('./worker.js');
        // myWorker.postMessage(40);
        // myWorker.onmessage = function(event){
        //     var data = event.data;
        //     console.log('worker 40获取'+data);
        // }
        // myWorker.onerror= function(event){
        //     console.log(event.fileName, event.lineo,event.message);
        // }
    </script>
    </html> 

    将js内容分别注释体验html页面的加载情况;

    self.onmessage = function(event){
        var data = event.data;
        var ans = fibonacci(data);
        this.postMessage(ans);
    }
    function fibonacci(n){
        return n<2?n:arguments.callee(n-1)+arguments.callee(n-2);
    }

    Web Worker 的作用,就是为 JavaScript 创造多线程环境,允许主线程创建 Worker 线程,将一些任务分配给后者运行。在主线程运行的同时,Worker 线程在后台运行,两者互不干扰。等到 Worker 线程完成计算任务,再把结果返回给主线程。这样的好处是,一些计算密集型或高延迟的任务,被 Worker 线程负担了,主线程(通常负责 UI 交互)就会很流畅,不会被阻塞或拖慢。

    关于webWorker可以参考:

      http://www.ruanyifeng.com/blog/2018/07/web-worker.html

      https://developer.mozilla.org/zh-CN/docs/Web/API/Worker

  • 相关阅读:
    JAVA面试题
    Io流
    初识线程池
    理解事务的4种隔离级别
    简单认识Git与GitHub
    JAVA自动装箱和拆箱
    代码块以及他们的执行顺序
    反射机制
    java Excel表格
    访问修饰符的含义分析
  • 原文地址:https://www.cnblogs.com/xhliang/p/10737270.html
Copyright © 2020-2023  润新知