如何使用 rxjs 重试 http 请求直到满足条件
How to retry a http request until a condition is met using rxjs
我想重试一个 http 请求,直到某些数据最多存在 10 次,每次重试之间有 2 秒的延迟。
const $metrics = from(axios(this.getMetrics(session._id, sessionRequest._id, side)));
const res = $metrics.pipe(
map((val: any) => {
console.log("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
- 我从 axios http promise 创建了
$metrics
observable。
- 我用map操作符检查http请求的响应是否符合我的条件重试。
val.data.metrics.length === 0
。如果是,则会抛出错误。
- 我最多重试 10 次 http 请求,延迟 10 秒。
我希望重试 3-4 次后此指标数组会有数据,但在我的控制台中,当我记录响应时,我得到以下信息。
VALUE: 0
我不确定这是否会发出多个 http 请求,因为控制台只记录 returns 一个输出而不是 10 个输出。
更新
我已经更新了代码以使用 retryWhen 而不是重试,它会延迟 2 秒并且在停止之前只会出现 10 个错误。
现在我认为问题是它只发出 1 个 http 请求,因为控制台只记录 returns 一个输出。
尝试使用 defer()
const $metrics = defer(()=>from(axios(this.getMetrics(session._id, sessionRequest._id, side))))
需要指出的一点是,您应该检查您的网络选项卡并查看是否在重试时发出了请求。您的 console.log 在 map() 运算符中,在抛出错误时将被跳过,这可能是您在那里看不到 console.log 的原因。您可以尝试下面的示例。
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.log(`fetcching you won't see`)))
const example = source.pipe(
retryWhen(errors =>
errors.pipe(
// log error message
tap(val => console.log(`retrying`)),
// restart in 5 seconds
delay(2000),
take(5),
),
),
)
我想重试一个 http 请求,直到某些数据最多存在 10 次,每次重试之间有 2 秒的延迟。
const $metrics = from(axios(this.getMetrics(session._id, sessionRequest._id, side)));
const res = $metrics.pipe(
map((val: any) => {
console.log("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
- 我从 axios http promise 创建了
$metrics
observable。 - 我用map操作符检查http请求的响应是否符合我的条件重试。
val.data.metrics.length === 0
。如果是,则会抛出错误。 - 我最多重试 10 次 http 请求,延迟 10 秒。
我希望重试 3-4 次后此指标数组会有数据,但在我的控制台中,当我记录响应时,我得到以下信息。
VALUE: 0
我不确定这是否会发出多个 http 请求,因为控制台只记录 returns 一个输出而不是 10 个输出。
更新
我已经更新了代码以使用 retryWhen 而不是重试,它会延迟 2 秒并且在停止之前只会出现 10 个错误。
现在我认为问题是它只发出 1 个 http 请求,因为控制台只记录 returns 一个输出。
尝试使用 defer()
const $metrics = defer(()=>from(axios(this.getMetrics(session._id, sessionRequest._id, side))))
需要指出的一点是,您应该检查您的网络选项卡并查看是否在重试时发出了请求。您的 console.log 在 map() 运算符中,在抛出错误时将被跳过,这可能是您在那里看不到 console.log 的原因。您可以尝试下面的示例。
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.log(`fetcching you won't see`)))
const example = source.pipe(
retryWhen(errors =>
errors.pipe(
// log error message
tap(val => console.log(`retrying`)),
// restart in 5 seconds
delay(2000),
take(5),
),
),
)