是否可以在每次重试后动态设置延迟值。我这样尝试过,但看起来很精巧,它保留了设置的初始值。
imageController(epgData: EpgDataDTO[], showOrMovie: string){
var retryAfterMilliSeconds = 1000;
epgData.forEach( (data) => {
this.getImagesFromMovieDB(data.title).pipe(
retryWhen((error) => {
return error.pipe(
mergeMap((error: any) => {
if(error.response.status === 429) {
const retryAfter = error.response.headers;
retryAfterMilliSeconds = +retryAfter['retry-after'] * 1000
console.log(retryAfterMilliSeconds); // it tells me the correct value here but the retry happens every 1000ms
console.log(data.title);
}else{
this.errorHandling(error)
return of("error");
}
return of("error");
}),
delay(retryAfterMilliSeconds),
take(5)
)
}))
.subscribe( (res) => {
console.log(res.status);
console.log(res.headers);
});
})
}
答案 0 :(得分:1)
您非常亲密!为了使它起作用,我所要做的就是将delay(retryAfterMilliSeconds)
运算符的返回值之后的mergeMap()
移到,以将其绑定到相同的可观察对象。如果没有此设置,它将随机延迟mergeMap()
的返回,而返回实际上是可观察的延迟。
我将其放在Stackblitz中进行测试。单击最右侧框架底部的“控制台”以查看结果。
这是该StackBlitz中的函数:
imageController(epgData: EpgDataDTO[], showOrMovie: string){
var retryAfterMilliSeconds = 1000;
epgData.forEach( (data) => {
this.getImagesFromMovieDB(data.title).pipe(
retryWhen((error) => {
return error.pipe(
mergeMap((error: any) => {
if(error.response.status === 429) {
const retryAfter = error.response.headers;
retryAfterMilliSeconds = +retryAfter['retry-after'] * 1000
console.log(retryAfterMilliSeconds); // it tells me the correct value here but the retry happens every 1000ms
console.log(data.title);
}else{
this.errorHandling(error)
// return of("error"); <-- unnecessary since this will be executed with next statement
}
return of("error").pipe(delay(retryAfterMilliSeconds));
}),
// delay(retryAfterMilliSeconds),
take(5)
)
}))
.subscribe(
(res) => {
// console.log(res.status);
// console.log(res.headers);
const elapsedTime = Math.round(((new Date()).getTime() - startTime) / 1000);
console.log(`'${res.status}' is Ok - total elapsed time ${elapsedTime} seconds`);
}
);
})
}
其他一些注意事项:
getImagesFromMovieDB()
的返回实际上很重要-它需要为每次调用返回一个唯一的可观察值,以使其正常工作,请确保确实如此。我通过使用delay
构造了Observable返回,在StackBlitz中对此进行了模拟。.subscribe()
内的第一个函数,以打印出获取该res.status
的有效数据所花费的总时间。我这样做只是为了表明每种发射正确地吸收了所有延迟的总和。
每次失败后都会随机重试一次(我在5到10秒之间任意选择),这由原始函数中的响应标头返回。return of("error")
中有两个返回值,但是第一个是不必要的,因为第二个将立即执行,所以我将其中一个注释掉。我希望这会有所帮助。