window.postMessage()在数据存在后发送数据

时间:2018-03-20 20:46:43

标签: javascript async-await es6-promise postmessage

我使用window.postMessage()在父窗口和嵌入式<iframe>之间发送数据。父窗口侦听&#34;已挂载&#34;来自<iframe>的消息,并发送带有JavaScript对象model的响应消息作为数据。

这是&#34;已挂载&#34;的父窗口事件监听器。消息:

window.addEventListener('message', (event) => {
  if (hasOwnProperty.call(event.data, 'mounted')) {
    $('iframe')[0].contentWindow.postMessage({ model }, '*');
  }
});

<iframe>可能会发送&#34;已安装&#34;在一个会话中多次发送消息,父窗口每次都需要回复model

但是,在初始页面加载时,父窗口从外部API异步检索model,该外部API可以在父窗口收到&#34; mount&#34;之前或之后解析。消息。

let model = {};
axios.get('/api/model')
  .then((response) => {
    model = response.data;
  });

因此,如果父窗口收到&#34;已挂载&#34;在模型存在之前的消息,我希望我的代码等到模型确实存在然后发送响应。我怎样才能做到这一点?我认为它会将我的postmessage({ model }, '*')电话转换为承诺,但我不确定如何附加该承诺以使其等待axios.get电话完成。

我知道Promise.all()是如何运作的,但是自从#{3}安装后,这并不会真正起作用。消息可以在窗口会话中多次发送。

一种解决方案

在写这个问题时,我意识到我可以编写一个仅在model isn't empty model时发送<iframe>的函数,这个函数我的#34;已安装&#34;事件监听器和我的异步数据检索可以调用。因此,当从外部API加载数据时,始终会发布消息(如果function postModel(model) { if (!_.isEmpty(model)) { $('iframe')[0].contentWindow.postMessage({ model }, '*'); } } let model = {}; axios.get('/api/model') .then((response) => { model = response.data; postModel(model); }); window.addEventListener('message', (event) => { if (hasOwnProperty.call(event.data, 'mounted')) { postModel(model); } }); 没有安装,则无关紧要),并且事件监听器仅在模型具有响应时响应加载。这是解决方案的完整代码:

{{1}}

这适用于我的目的,但我仍然有兴趣看看是否有更好的async / await方法。

1 个答案:

答案 0 :(得分:0)

也许你会发现想要使用frameTalk.js。 FrameTalk支持iframe之间的Promise。所以,你会像那样做什么

    frameTalk.sendPromise(window.top, "myFrameID", "methodNameToRun", ["methodAttributesToPass"])
.then(doOnSuccess, doOnFail);

详情请见 https://github.com/inedu/frameTalk