首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在retryWhen上设置延迟动态

在retryWhen上设置延迟动态
EN

Stack Overflow用户
提问于 2019-01-04 01:48:11
回答 1查看 352关注 0票数 2

是否可以在每次重试后动态设置延迟值。我试着这样做,但它看起来很小,它保留了初始设置的值。

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);

        });
    })
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-04 07:39:03

你们差一点就到了!要使其正常工作,我所要做的就是将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.
  • As构造可观察的返回,在StackBlitz中模拟了这一点,您可以看到,我更改了.subscribe()中的第一个函数,以打印出获取此res.status的有效数据所用的总运行时间。我这样做只是为了说明每个发射都正确地取了所有延迟的总和。它会在每次失败后随机重试一段时间(我在5到10秒之间随意选择),正如原始function.
  • Minor点中的响应头所返回的那样:您有两个来自mergeMap return of("error")的返回,但第一个是不必要的,因为第二个将立即执行,所以我注释掉了那个。

我希望这能帮到你。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54027303

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档