MessageChannel 消息通道

1、初識 MessageChannel 對象html

經過構造函數 MessageChannel() 能夠建立一個消息通道,實例化的對象會繼承兩個屬性:port1port2html5

port1 和 port2 都是 MessagePort 對象,在這裏是只讀的,沒法對其進行字面量賦值web

不過能夠給 port 添加屬性跨域

上圖還體現了 MessagePort 對象具備 onmessageonmessageerror 兩個屬性數組

這是兩個回調方法,使用 MessagePort.postMessage 方法發送消息的時候,就會觸發另外一個端口的 onmessage多線程

 

消息通道就像是一條左右貫通的管道,左右兩個端口就是 port1 和 port2異步

這兩個端口能夠相互發送消息,port1 發送的消息能夠在 port2 接收到,反之亦然async

 

 

2、多個 Web Worker 之間通訊wordpress

MessageChannel 能夠結合 Web Worker 實現多線程通訊函數

// main.js
 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]); worker2.onmessage = function(event) { console.log(event.data); }

這裏的 postMessage() 能夠接收兩個參數:message、transferList

message 消息內容,能夠是任意基礎數據類型
transferList 由被傳輸對象組成的數組,這些對象的全部權會轉移給調用 postMessage 的對象

 

 

 

因此上面的代碼,就是把消息通道的 port1 分配給了 worker1,把 port2 分配給 worker2

也就是用消息通道,將兩個 worker 給鏈接起來

// worker1.js onmessage = function(e) { if (e.data === 'main') { const port = e.ports[0]; port.postMessage('Hi! I'm worker1'); } }
// worker2.js
onmessage = function(e) { if (e.data === 'main') { const port = e.ports[0]; port.onmessage = function(e) { postMessage(e.data); } } }

代碼運行的時候,worker1 中經過 port1 發送消息,而後 worker2 就能從 port2 中接收到消息

 

3、深拷貝

大部分須要深拷貝的場景,均可以使用如下代碼:

JSON.parse(JSON.stringify(object))

但這種辦法會忽略 undefined、function、symbol循環引用的對象

而經過 postMessage() 方法傳輸的 message 參數是深拷貝的

因此能夠借用 MessageChannel 實現深拷貝:

// 深拷貝函數
function deepClone(val) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel() port2.onmessage = e => resolve(e.data) port1.postMessage(val) }) } // 定義一個包含 undefined 的對象
let obj = { a: 'wise', b: undefined, c: { d: 'wrong' } } // 循環引用
obj.c.e = obj.c // 注意該方法是異步的
async function test() { const clone = await deepClone(obj) console.log(clone) } test()

但這個深拷貝只能解決 undefined循環引用對象的問題,對於 Symbolfunction 依然一籌莫展

 

 

參考資料:

《HTML5 postMessage iframe跨域web通訊簡介》

《MessageChannel是什麼,怎麼使用?》

相關文章
相關標籤/搜索