Как повторить HTTP-запрос, пока не будет выполнено условие, используя rxjs

Я хочу повторить http-запрос, пока некоторые данные не будут существовать до 10 раз с задержкой в ​​2 секунды между каждой повторной попыткой.

const $metrics = from(axios(this.getMetrics(session._id, sessionRequest._id, side)));

const res = $metrics.pipe(
  map((val: any) => {
    console.info("VALUE:", val.data.metrics.length);
    if (val.data.metrics.length === 0) {
      throw val;
    }
    return val;
  }),
  retryWhen((errors) => errors.pipe(delay(2000), take(10))),
).subscribe();

Я пытаюсь следовать примеру в документации. https://www.learnrxjs.io/operators/error_handling/retry.html

  1. Я создаю $metrics наблюдаемое из обещания axios http.
  2. Я использую оператор карты, чтобы проверить, соответствует ли ответ http-запроса моему условию повторной попытки. val.data.metrics.length === 0. Если да, то выдает ошибку.
  3. Я повторяю http-запросы до 10 раз с 10-секундной задержкой.

Я ожидаю, что после 3-4 попыток для этого массива метрик будут данные, но в моей консоли, когда я регистрирую ответ, я получаю следующее.

VALUE: 0

Я не уверен, что это даже делает несколько HTTP-запросов, потому что журнал консоли возвращает только один вывод вместо 10.

ОБНОВИТЬ

Я обновил код, чтобы использовать retryWhen вместо повторной попытки, он выполняет задержку в 2 секунды и принимает только 10 ошибок перед остановкой.

Теперь я считаю, что проблема в том, что он делает только 1 HTTP-запрос, потому что журнал консоли возвращает только один вывод.

поставьте delay(2000) после повторной попытки и посмотрите, что получится. Что касается сетевого вызова из-за from(axios(options));, что именно это делает?

Goga Koreli 21.05.2019 12:42

axios — это клиентская библиотека http, которая превращает http-запрос в наблюдаемый объект.

Kay 21.05.2019 12:42

Возвращает ли axios уже Observable? Зачем тебе from()?

Goga Koreli 21.05.2019 12:43

from преобразует обещание axios в наблюдаемое

Kay 21.05.2019 12:44

Также вы видите в инспекторе сети все запросы и ответы на них? Вы видите, что в ответ отправляются правильные данные?

Goga Koreli 21.05.2019 12:44

да, я отправляю правильный запрос

Kay 21.05.2019 12:45

Пишите throw 'data empty'; вместо return throwError('data empty'); при использовании retryWhen()

Goga Koreli 21.05.2019 13:07

да я уже изменил это

Kay 21.05.2019 13:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
8
5 315
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

попробуйте использовать отсрочку()

const $metrics = defer(()=>from(axios(this.getMetrics(session._id, sessionRequest._id, side))))

Следует отметить одну вещь: вы должны проверить вкладку сети и посмотреть, выполняется ли повторный запрос. ваш console.info находится в операторе map(), который будет пропущен при возникновении ошибки, возможно, поэтому вы не видите там console.info. Вы можете попробовать пример ниже.

import { timer, interval,from } from 'rxjs';
import { map, tap, retryWhen, delayWhen,delay,take } from 'rxjs/operators';

//emit value every 1s
const source = from(fetch('http://kaksfk')).pipe(tap(val => console.info(`fetcching you won't see`)))
const example = source.pipe(
  retryWhen(errors =>
    errors.pipe(
      // log error message
      tap(val => console.info(`retrying`)),
      // restart in 5 seconds
      delay(2000),
      take(5),
    ),
  ),
)

Эта отсрочка не помогла, что она здесь пытается сделать?

Kay 21.05.2019 15:50

эта наблюдаемая завернута в функцию, которая является асинхронной, нужно ли ждать где-нибудь в этой наблюдаемой?

Kay 21.05.2019 16:05

возвращает ли axio обещание? from уже преобразовал это в наблюдаемое, так что это не имеет значения

Fan Cheung 21.05.2019 16:35

Обновлен ответ

Fan Cheung 21.05.2019 17:34

спасибо, эта отсрочка помогла, но тогда у меня возникла проблема с продолжением. stackoverflow.com/questions/56341838/…

Kay 28.05.2019 15:06

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