Я хочу повторить 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
$metrics
наблюдаемое из обещания axios http.val.data.metrics.length === 0
. Если да, то выдает ошибку.Я ожидаю, что после 3-4 попыток для этого массива метрик будут данные, но в моей консоли, когда я регистрирую ответ, я получаю следующее.
VALUE: 0
Я не уверен, что это даже делает несколько HTTP-запросов, потому что журнал консоли возвращает только один вывод вместо 10.
ОБНОВИТЬ
Я обновил код, чтобы использовать retryWhen вместо повторной попытки, он выполняет задержку в 2 секунды и принимает только 10 ошибок перед остановкой.
Теперь я считаю, что проблема в том, что он делает только 1 HTTP-запрос, потому что журнал консоли возвращает только один вывод.
axios — это клиентская библиотека http, которая превращает http-запрос в наблюдаемый объект.
Возвращает ли axios уже Observable? Зачем тебе from()
?
from преобразует обещание axios в наблюдаемое
Также вы видите в инспекторе сети все запросы и ответы на них? Вы видите, что в ответ отправляются правильные данные?
да, я отправляю правильный запрос
Пишите throw 'data empty';
вместо return throwError('data empty');
при использовании retryWhen()
да я уже изменил это
попробуйте использовать отсрочку()
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),
),
),
)
Эта отсрочка не помогла, что она здесь пытается сделать?
эта наблюдаемая завернута в функцию, которая является асинхронной, нужно ли ждать где-нибудь в этой наблюдаемой?
возвращает ли axio обещание? from
уже преобразовал это в наблюдаемое, так что это не имеет значения
Обновлен ответ
спасибо, эта отсрочка помогла, но тогда у меня возникла проблема с продолжением. stackoverflow.com/questions/56341838/…
поставьте
delay(2000)
после повторной попытки и посмотрите, что получится. Что касается сетевого вызова из-заfrom(axios(options));
, что именно это делает?