利用 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



猜您在找