postmessage雙向通信中,是不能使用回調函數的。
window.postmessage({msg:'hello',callback:function(e){ do something with e }})
這樣是不行的,js會提示function不會被克隆。
我猜啊因為postmessage是通過dom通訊,js對象會被json化
也就是說不能傳遞方法。
不過,話說回來,有什么不能的呢,大不了,把function tostring一下,也是可以傳過去的。
那這里就要考慮你傳callback是干什么用了,如果是作為一種自定義 的數據處理方法,你就tostring一下,過去隨便用用就好了,就好像foreach那樣,傳一個方法,在foreach內部用用。
如果就是想要得到返回值,讓自己的書寫比較連續。業務邏輯比較連續,callback的結果不會再傳到對面。也就是說,callback始終是在本window下運行的。
保持業務邏輯連續的在你所寫的方法里,不會因為調用postmessage而把業務處理邏輯跳躍到onmessage里。
這是我要在這里討論的。
1.很顯然,callback從來沒真正被傳遞到對面window里。
2.callback將在onmessage(addlistoner里注冊的接收事件)里執行。
3.基於以上兩點 ,可以得出很簡單的結論。在本window里緩存callback,等onmessage接收到對面發回來的數據時,用callback處理即可。
話有點兒繞嘴,分步來一次,應該會更清楚一點。
1.用postmessage發消息給對面。
2.對面收到消息,處理,
3.用postmessage給本地發消息。
4.本地接收到消息,處理
那么本地要用callback去處理,要知道用的是哪個function去處理。那么本地有一個指向callback的變量,就可以得到該callback。
而因為通訊不可能只一次,該callback會被放在數組里,同時會用唯一性id來標示它,而這個標示 也將被告訴對面window,再讓對面告訴本地,從而,本地的接收事件中,去調用這個function。
還是繞,
寫一下代碼吧,也許代碼一目了然。
對面的接收單元
window.addEventListener("message", function(e) { var data = e.data //拿到傳遞的數據 {msg:'給我來杯可樂',callbackid:'15146484468'} //打一杯可樂 var res = '返回的可樂' window.postmessage({result:res,callbackid:data.callbackid})//發出去 }, false);
本地的單元
var callbacks : {}
function 點杯可樂(callback){ callbacks[隨機id] = callback xxxwindow.postmessage ({msg:'給我打一杯可樂',callbackid:'隨機id'}) } function 吃肯德基的方法(){ //點漢堡 點漢堡(吃漢堡的方法) //點可樂 點杯可樂(喝可樂) //結賬走人了 } //喝可樂就是callback對吧 function 喝可樂(){ //咚咚咚。。。哈 }
很顯然,吃肯德基就是業務,那么業務順序就是如此的,如果突然跳到接收事件里去吃漢堡,喝可樂,總是很詭異的。
通過,緩存callback假裝callback被傳遞出去,然后被調用,其實,就達到了目的。
以上。