Отмените предыдущие запросы и выполняйте только последний запрос с наблюдаемым избыточным количеством - PullRequest
0 голосов
/ 03 мая 2018

Таким образом, у меня есть сценарий использования, когда я обновляю запрос api при перемещении карты - но он может генерировать несколько быстрых запросов на выстрел с небольшими движениями карты - и я хочу отменить все запросы на полеты, кроме последнего. Я могу использовать debounce, чтобы отправлять запросы только после задержки. Однако я все еще хочу отменить все старые запросы, если они все еще обрабатываются.

const fetchNearbyStoresEpic = action$ =>
  action$.ofType(FETCH_NEARBY_STORES)
    .debounceTime(500)
    .switchMap(action =>
      db.collection('stores')
        .where('location', '<=', action.payload.max).
        .where('location', '>=', action.payload.min)
        .map(response => fetchNearbyStoresFulfilled(response))
        .takeUntil(action$.ofType(FETCH_STORES_CANCELLED))
    );

Я вижу, что вы можете использовать takeUntil, но вам нужно явно запустить действие отмены. В документации я вижу, что switchMap примет последнюю версию и отменит все остальные. Нужно ли мне реализовывать интерфейс отмены в вызове API? В этом случае это будет пожарный запрос к firestore.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Из комментария , который я сделал в выпуске GitHub:

Поскольку они имеют измерение времени, для наблюдаемых существует несколько стратегий выравнивания:

  • С mergeMap (который имеет flatMap в качестве псевдонима), полученные наблюдаемые объекты одновременно подписываются, а их излучаемые значения сливаются в выходной поток.
  • При concatMap полученные наблюдаемые ставятся в очередь и подписываются друг за другом по завершении каждого. (concatMap равен mergeMap с параллелизмом, равным единице.)
  • При switchMap, когда получено наблюдаемое, оно подписывается и любая подписка на ранее полученное наблюдаемое отменяется.
  • При exhaustMap, когда наблюдаемая принимается, она подписывается, если нет подписки на ранее полученную наблюдаемую и эта наблюдаемая еще не завершена - в этом случае полученная наблюдаемая игнорируется.

Итак, как сказал Марк в своем ответе, когда switchMap получит последующее действие, оно отменит подписку на любой неполный запрос.

Однако запрос не будет отменен до тех пор, пока отклоненное действие не достигнет switchMap. Если вы хотите отменить любые отложенные запросы сразу после другого перемещения - вместо того, чтобы ждать продолжительности отката - вы можете использовать takeUntil с действием FETCH_NEARBY_STORES:

const fetchNearbyStoresEpic = action$ =>
  action$.ofType(FETCH_NEARBY_STORES)
    .debounceTime(500)
    .switchMap(action =>
      db.collection('stores')
        .where('location', '<=', action.payload.max).
        .where('location', '>=', action.payload.min)
        .map(response => fetchNearbyStoresFulfilled(response))
        .takeUntil(action$.ofType(FETCH_NEARBY_STORES))
    );

Это должно привести к немедленной отмене подписки на запрос при следующем перемещении. (В верхней части головы я не могу вспомнить поведение action$ в redux-observable. Возможно, вам может понадобиться добавить skip(1) к наблюдаемому результату, переданному в takeUntil. Попробуйте и посмотрите.)

И, как отметил Марк, это основано на базовой реализации, отменяющей запрос при отмене подписки.

0 голосов
/ 04 мая 2018

switchMap откажется от своей предыдущей наблюдаемой, когда через нее будет отправлено новое излучение. В зависимости от вашей базовой библиотеки HTTP и от того, поддерживает ли она отмену (Observable осведомлена), этого должно быть достаточно.

Поскольку в вашем вопросе не было предоставлено никаких подробностей реализации, вам придется заглянуть в fetchNearbyStoresFulfilled, чтобы узнать, использует ли он http-клиент с поддержкой Observable. Если он использует обещания, поддержка отмены не предоставляется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...