I cant get async-await to work when using postMessage and a MessageChannel
const iframe = document.querySelector("iframe");
const sendMsgOnPort = async (msg) => {
const channel = new MessageChannel();
const testfunc = async () => {
channel.port1.onmessage = ({ data }) => {
channel.port1.close();
if (data.error) {
return data.error;
} else {
return data.result;
}
};
};
iframe.contentWindow.postMessage(`${msg}`, "*", [channel.port2]);
await testfunc();
};
iframe.addEventListener(
"load",
async () => {
console.log(await sendMsgOnPort("msg"));
},
true
);
and the child I have
window.addEventListener("message", (event) => {
try {
event.ports[0].postMessage({ result: `${event.data} back` });
} catch (e) {
event.ports[0].postMessage({ error: e });
}
});
I can get it to work with
const sendMsgOnPort = (msg) =>
new Promise((res, rej) => {
const channel = new MessageChannel();
channel.port1.onmessage = ({ data }) => {
channel.port1.close();
if (data.error) {
rej(data.error);
} else {
res(data.result);
}
};
iframe.contentWindow.postMessage(`${msg}`, "*", [channel.port2]);
});
but is there a way to do this without the new Promise((res, rej) => {
No.
You can only (usefully) await a promise.
You need new Promise to create one if you don't have one already (e.g. if the underlying API you are using returns a promise).
You don't have one already (not least because onmessage is a callback API designed to handle ๐ messages, not 1 message).