Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
试图理解这个retryWhen/scan/delay rxjs序列_Rxjs - Fatal编程技术网

试图理解这个retryWhen/scan/delay rxjs序列

试图理解这个retryWhen/scan/delay rxjs序列,rxjs,Rxjs,因此,我提出了一个HTTP请求延迟重试的实现,它工作得很好,我对它也有很好的理解 retryWhen(err => { let retryCount = 0; let nextDelay = 0; backoff = backoff < 0 || backoff === null ? DEFAULT_BACKOFF : backoff; maxDelay = maxDelay < 0 || maxDelay === null ? DEFAULT_

因此,我提出了一个HTTP请求延迟重试的实现,它工作得很好,我对它也有很好的理解

retryWhen(err => {
    let retryCount = 0;
    let nextDelay = 0;
    backoff = backoff < 0 || backoff === null ? DEFAULT_BACKOFF : backoff;
    maxDelay = maxDelay < 0 || maxDelay === null ? DEFAULT_MAX_DELAY : maxDelay;

    return err.pipe(
      scan(idx => {
        if (idx > maxRetries - 1) {
          throw err;
        } else {
          idx++;
          retryCount = idx;
          nextDelay = Math.min(retryDelay + ((retryCount - 1) * backoff), maxDelay);

          return idx;
        }
      }, 0),
      tap(v => console.log(`Waiting ${nextDelay} ms for Retry #${retryCount}...`)),
      delay(nextDelay),
      tap(v => console.log(`Initiating HTTP Retry for context ${context}`))
    )

扫描将原始的
err
元素映射到索引
idx
,但是如何在
delay
操作符中准确地得到它呢?

传递给
retryWhen的函数在第一个错误时只调用一次。因此,在创建可观察的
err.pipe(…)
时(而不是在
err
发出时),会调用一次
delay(nextDelay)
。当时
nextDelay
仍然是
0
。您应该将所有逻辑放在一个运算符中,该运算符根据
err
发出的值返回不同的值

要返回发射延迟变化的可见光,您可以将
mergeMap
映射到
计时器。这应该让你开始:

接口RetryStrategyConfig{
maxRetryAttempts?:数字;
缩放持续时间?:数字;
maxDelay?:数字;
excludedStatusCodes?:编号[];
}
功能通用系统策略({
maxRetryAttempts=6,
缩放持续时间=1000,
最大延迟=5000,
excludedStatusCodes=[]
}:RetryStrategyConfig={}){
返回(尝试次数:可观察)=>{
回流管(
合并映射((错误,i)=>{
const retrytry=i+1;
//如果已达到最大重试次数
//或者响应是我们不希望重试的状态代码,抛出错误
如果(
重试次数>最大重试次数||
excludedStatusCodes.find(e=>e==error.status)
) {
返回投掷器(错误);
}
const nextDelay=Math.min(重试*缩放持续时间,最大延迟);
log(`trunt${retrytrunt}:在${nextDelay}ms`中重试);
返回计时器(下一个延迟);
}),
完成(()=>console.log(“我们完成了!”)
);
};
}
obs美元管道(
retryWhen(genericRetryStrategy())
)

传递给
retryWhen的函数在第一个错误时只调用一次。因此,在创建可观察的
err.pipe(…)
时(而不是在
err
发出时),会调用一次
delay(nextDelay)
。当时
nextDelay
仍然是
0
。您应该将所有逻辑放在一个运算符中,该运算符根据
err
发出的值返回不同的值

要返回发射延迟变化的可见光,您可以将
mergeMap
映射到
计时器。这应该让你开始:

接口RetryStrategyConfig{
maxRetryAttempts?:数字;
缩放持续时间?:数字;
maxDelay?:数字;
excludedStatusCodes?:编号[];
}
功能通用系统策略({
maxRetryAttempts=6,
缩放持续时间=1000,
最大延迟=5000,
excludedStatusCodes=[]
}:RetryStrategyConfig={}){
返回(尝试次数:可观察)=>{
回流管(
合并映射((错误,i)=>{
const retrytry=i+1;
//如果已达到最大重试次数
//或者响应是我们不希望重试的状态代码,抛出错误
如果(
重试次数>最大重试次数||
excludedStatusCodes.find(e=>e==error.status)
) {
返回投掷器(错误);
}
const nextDelay=Math.min(重试*缩放持续时间,最大延迟);
log(`trunt${retrytrunt}:在${nextDelay}ms`中重试);
返回计时器(下一个延迟);
}),
完成(()=>console.log(“我们完成了!”)
);
};
}
obs美元管道(
retryWhen(genericRetryStrategy())
)
第一个问题:当我在delay操作符中使用一个常量值(如so delay(3000))时,上面的代码可以正常工作,但当我使用nextDelay变量时,它不能正常工作。当我使用nextDelay变量时,没有延迟,就像变量为零一样

这一问题的原因已经在报告中指出

但是,该值在tap运算符中正确输出

这暗示着你可以解决它。区别在于
delay(value)
捕获
,在
点击(()=>…)
的情况下,每次调用其回调函数时(在本例中,每次
下一次
通知时),都会对
进行评估

如果我们看看

导出函数延迟(到期日期:number |日期,调度程序:SchedulerLike=asyncScheduler):MonoTypeOperatorFunction{
const duration=计时器(到期,调度程序);
返回delayWhen(()=>持续时间);
}
我们将看到它首先捕获
计时器
可观察值中的值,然后与
delayWhen
一起使用

因此,第一个问题可以通过以下方式解决:

/**/
轻触(v=>console.log(`Waiting${nextDelay}ms for Retry#${retryCount}…`)),
延迟时间(()=>计时器(下一个延迟)),
轻触(v=>console.log(`Initiating HTTP Retry for context${context}`))
/* ... */
第二个问题:我想优化上面的代码,这样我就不会使用变量retryCount和nextDelay

我们可以使用其他RxJS操作符来实现这一点:

retryWhen(err=>{
退避=退避<0 | |退避===null?默认值_退避:退避;
maxDelay=maxDelay<0 | | maxDelay===null?默认值_MAX_DELAY:maxDelay;
返回错误管道(
//将'retryCount'替换为'map'的索引参数
映射((错误,idx)=>{
//您也可以在这里抛出错误
如果(idx>=maxRetries){throw err;}
const retryCount=idx+1;
//返回'nextDelay'`
返回Math.min(retryDelay+((retryCount-1)*退避),maxDelay;
})
延迟时间(nextDelay=>timer(nextDelay)),
)
第一个问题:当我在delay操作符中使用一个常量值(如so delay(3000))时,上面的代码可以正常工作,但当我使用nextDelay变量时,它不能正常工作。当我使用nextDelay变量时,没有延迟,就像变量为零一样

问题的原因已在中指出。

scan(idx => ... code to either throw the error or emit the index ...), delay(idx => Math.min(retryDelay + (idx - 1) * backoff), maxDelay)