Как идентифицировать задачи web worker через postMessage?

Общение со сторонним API выношу в web worker, чтобы не тормозил интерфейс. Запросы к API ограничены по частоте.

Инициируются запросы из разных мест в коде и надо как-то понимать, кому из ожидающих Promise'ов поступил очередной ответ.

Думаю, генерировать для каждой асинхронной «задачи» уникальный/случайный хэш. Передавать его в Worker вместе с данными для запроса, и при получении сообщения от Worker'а, каждый смотрит, не его ли хэш пришел с ответом.
new Promise((resolve, reject) => {
  const hash = Math.random();
  Worker.postMessage({
    hash: hash,
    otherData: 'other data'
  });
  Worker.addEventListener('message', m => {
    if(m.data.hash != hash) return;
    // наш ответ подоспел! Пляшем.
  });
})


Насколько это правильный подход и есть ли другие варианты решения задачи?
  • Вопрос задан
  • 107 просмотров
Решения вопроса 1
Vlad_IT
@Vlad_IT Куратор тега JavaScript
Front-end разработчик
Вообще, встроенного механизма для такой задачи нет, т.к. все, что у нас есть, это postMessage, который умеет передавать только примитивы и Transferable объекты. Я вижу 2 варианта
1) Который вы предложили. Передавать хеш и потом при получении сообщения сравнивать. Только лучше делать не через замыкание (как у вас), а создать массив слушателей. Но это уже вылетает способ 2:
2) Сделать глобальную шину событий. Чтобы подписчики могли подписываться следующим образом
eventBase.on('worker.getLogin', function() { });
eventBase.on('worker.getEmail', function() { });

а в onmessage воркера просто запускать это событие
Worker.addEventListener('message', m => {
    eventBase.emit(`worker.${m.eventName}`);
});
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы