Redux observable - разрешение нескольких действий - async

Я пытаюсь внедрить сторонний скрипт на страницу и после его загрузки инициализировать видеоплеер.

Я хочу иметь несколько видеопроигрывателей на любой странице, поэтому у меня есть логика, чтобы проверить, загружен ли уже скрипт, и запускать различные действия в зависимости от того, загружен он или нет.

Мой помощник по загрузке скрипта выглядит так:

  /**
   * injectScript - Inject player script into page
   * @param {String} id - script tag id
   * @param {String} src - script src
   * @return {Promise} - script load callback
   */
  injectScript (id, src) {
    return new Promise(resolve => {
      if (!document.getElementById(id)) {
        const script = document.createElement('script');
        script.setAttribute('id', id);
        script.type = 'text/javascript';
        script.src = src;
        document.body.appendChild(script);

        script.onload = () => resolve('script-loaded');
      } else {
        resolve('script-exists');
      }
    });
  }

Затем у меня есть эпос, который вызывает этого помощника и запускает действие в зависимости от результата. Эпопея выглядит так:

/**
 * loadPlayerScript
 * @param {Object} action$ - action observable
 * @param {Object} store - redux store
 * @param {Object} dependencies - injected dependencies
 * @return {Object} - action observable
 */
export default function loadPlayerScript (action$, store, { scriptLoaderHelper }) {
  return action$.ofType(PLAYER_SCRIPT_LOAD)
    .switchMap(action => Observable.fromPromise(scriptLoaderHelper.injectScript(action.data.id, action.data.script)))
    .map(data => {
      if (data === 'script-loaded') {
        return playerScriptSuccess();
      }

      return playerScriptExists();
    })
    .catch(error => Observable.of(playerScriptFailure(error)));
}

Проблема:

PLAYER_SCRIPT_LOAD запускается дважды (я могу проверить это в инструментах разработки Redux), это ожидаемо. Но что происходит, так это то, что эпос выполняет обещание только один раз (и запускает только одно из действий на карте). Как мне заставить эпос запускать действия для каждого разрешения обещания?

Я уверен, что это что-то очень простое, на что я не обращаю внимания, но любая помощь приветствуется!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
175
1

Ответы 1

Измените switchMap на mergeMap, чтобы избежать отмены:

The main difference between switchMap and other flattening operators is the cancelling effect. On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.

источник: https://www.learnrxjs.io/operators/transformation/switchmap.html

Другие вопросы по теме