В вашем коде есть очевидные проблемы и анти-паттерны.cookieAvailable
вернет Обещание, поэтому ваш чек if(!!cookieAvailable()) {
всегда будет правдивым.Вам следует подождать, пока это Обещание не будет выполнено, прежде чем проверять, действительно ли доступен файл cookie.
Но на самом деле ваша функция cookieAvailable
возвращает упаковку Обещания даром: если thisChatClient.cookie.getCookieData
действительно возвращает Обещание, то возвращайте его напрямую, нет необходимости заключать его в Обещание.синхронный результат, тогда вы проиграете, только обернув его в Обещание
async function requestCommunication(topic, customerId) {
function cookieAvailable() {
// this is already a Promise
return thisChatClient.cookie.getCookieData('sess_au');
}
const isCookieAvailable = await cookieAvailable();
if (!!isCookieAvailable) {
}
}
requestCommunication().catch(console.error);
Теперь все это не может помочь сделать правильный ответ на ваш вопрос: связь между вашими блоками кодане совсем понятно.
Ничто не вызывает ни функции.
Ваш getCookieData
будет ожидать MessageEvent, не сообщая никому, что он его ждет.
Я не уверен, как вы запланировали, чтобы ваш iframe знал, что он должен отправить сообщение с этой информацией в ваше окно, но это то, что вы должны рассмотреть.
Но прежде чем идти тудаЯ должен отметить: как бы заманчиво это ни было, упаковывать события в Promises, как правило, плохая идея.
События и Обещания - это разные вещи, последние должны разрешаться только один раз, в то время как первые могут срабатывать несколько раз и из разных источников.
IMM это хорошо делать только тогда, когда вы уверены, что событие сработает только один раз.С MessageEvent, вы далеки от его знания.
Ваш пользователь вполне может иметь расширение в своем браузере, которое будет использовать postMessage в качестве средства для общения.Если это расширение добавлено во все iframes, ваш код не работает.
Вместо этого вы должны проверить MessageChannel API , который предложит вам средство общения, которое вы можете быть уверены, что будете использовать только вы.
Я не думаю,этот ответ - правильное место, чтобы объяснить, как работает этот API, но взгляните на этот обзор , который объясняет самые основы.
Так как вы обязательно будете контролировать обаПосле этого вы можете настроить систему на основе Promise.
На главной странице вы подготовите объект MessageChannel и отправите его в iframe, ожидая ответа.Когда придет этот ответ, вы сможете выполнить свое Обещание.
В своем фрейме вы добавите в окно прослушиватель для перехвата MessageChannelPort.Когда это происходит, вы запрашиваете cookie-файл у своей службы и отправляете его обратно через порт MessageChannel.
Даже если во время этого обмена в вашем главном окне появляется сообщение, вы можете быть уверены, что оно не будетбудь тем, кого ты ждешь.
// Sets up a new MessageChannel
// so we can return a Promise
function getCookieData() {
return new Promise((resolve) => {
const channel = new MessageChannel();
// this will fire when iframe will answer
channel.port1.onmessage = e => resolve(e.data);
// let iframe know we're expecting an answer
// send it its own port
frame.contentWindow.postMessage('getCookie', '*', [channel.port2]);
});
}
frame.onload = async e => {
const frameHasCookie = await getCookieData();
console.log(frameHasCookie);
};
frame.src = generateFrameSRC();
function generateFrameSRC() {
// The content of your iframe
const cont = `
<html>
<head>
<script>
const originClean = "null";
onmessage = async e => {
// only if it's the origin we expected
// and if it does send a MessagePort
// and the message is "getCookie"
if(e.origin === originClean && e.ports && e.data === "getCookie") {
const data = await asyncData();
// respond to main window
e.ports[0].postMessage(data);
}
};
function asyncData() {
return new Promise(resolve =>
setTimeout(() => resolve("the data"), 1000)
);
}
<\/script>
</head>
<body>
hello
</body>
</html>`;
return 'data:text/html,' + encodeURIComponent(cont)
}
<iframe id="frame"></iframe>