在重试时设置动态延迟
set delay dynamic on retryWhen
是否可以在每次重试后动态设置延迟值。我这样试过,但它看起来很简单,它保留了初始设置的值。
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);
});
})
}
你们非常接近!为了让它工作,我所要做的就是将 delay(retryAfterMilliSeconds)
移动到 mergeMap()
运算符的 return 值之后,以将其绑定到同一个可观察对象。如果没有这个,它会随机地延迟 mergeMap()
的 RETURN ,这将是随机的,而 Observable 实际上被延迟了。
我把它放在 Stackblitz 中进行测试。单击最右侧框架底部的 'Console' 查看结果。
这是 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()
中的 return 实际上很重要 - 它需要 return 每次调用都有一个唯一的可观察对象才能正常工作,请确保是这种情况。我在 StackBlitz 中通过使用 delay
. 构造 Observable return 来模拟这一点
- 如您所见,我更改了
.subscribe()
中的第一个函数,以打印出为该 res.status
获取有效数据所花费的总运行时间。我这样做只是为了表明每次发射都正确地计算了所有延迟的总和。
每次失败后都会重试一段随机时间(我在 5 到 10 秒之间任意选择),正如 return 由原始函数中的响应 header 编辑的那样。
- 要点:您有两个来自 mergeMap
return of("error")
的 return,但第一个是不必要的,因为第二个将立即执行,所以我评论了那个。
希望对您有所帮助。
是否可以在每次重试后动态设置延迟值。我这样试过,但它看起来很简单,它保留了初始设置的值。
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);
});
})
}
你们非常接近!为了让它工作,我所要做的就是将 delay(retryAfterMilliSeconds)
移动到 mergeMap()
运算符的 return 值之后,以将其绑定到同一个可观察对象。如果没有这个,它会随机地延迟 mergeMap()
的 RETURN ,这将是随机的,而 Observable 实际上被延迟了。
我把它放在 Stackblitz 中进行测试。单击最右侧框架底部的 'Console' 查看结果。
这是 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()
中的 return 实际上很重要 - 它需要 return 每次调用都有一个唯一的可观察对象才能正常工作,请确保是这种情况。我在 StackBlitz 中通过使用delay
. 构造 Observable return 来模拟这一点
- 如您所见,我更改了
.subscribe()
中的第一个函数,以打印出为该res.status
获取有效数据所花费的总运行时间。我这样做只是为了表明每次发射都正确地计算了所有延迟的总和。 每次失败后都会重试一段随机时间(我在 5 到 10 秒之间任意选择),正如 return 由原始函数中的响应 header 编辑的那样。 - 要点:您有两个来自 mergeMap
return of("error")
的 return,但第一个是不必要的,因为第二个将立即执行,所以我评论了那个。
希望对您有所帮助。