Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.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
Angular 在http请求管道中使用rxjs repeatWhen,以便在未返回所需响应时重复请求_Angular_Rxjs_Rxjs Observables_Rxjs Pipeable Operators - Fatal编程技术网

Angular 在http请求管道中使用rxjs repeatWhen,以便在未返回所需响应时重复请求

Angular 在http请求管道中使用rxjs repeatWhen,以便在未返回所需响应时重复请求,angular,rxjs,rxjs-observables,rxjs-pipeable-operators,Angular,Rxjs,Rxjs Observables,Rxjs Pipeable Operators,我正在尝试使用下面简化的http请求管道版本,以确保如果我的响应在res.myCondition中没有所需的数据,则可以使用repeatWhen并进行另一次调用,但我显然没有按预期的方式使用repeatWhen。(角度8/rxjs 6.5) 目的是让第一个调用进入映射,在映射中我检查返回的数据,如果数据在那里,我将在我的组件中将其返回给订阅者,但是如果res中缺少myCondition,我希望在reties中重复api调用预定的次数 关于我的repeatWhen实现哪里出了问题,有什么想法吗 方

我正在尝试使用下面简化的http请求管道版本,以确保如果我的响应在res.myCondition中没有所需的数据,则可以使用repeatWhen并进行另一次调用,但我显然没有按预期的方式使用repeatWhen。(角度8/rxjs 6.5)

目的是让第一个调用进入映射,在映射中我检查返回的数据,如果数据在那里,我将在我的组件中将其返回给订阅者,但是如果res中缺少myCondition,我希望在reties中重复api调用预定的次数

关于我的repeatWhen实现哪里出了问题,有什么想法吗

方法1:

return this.http.get()
   .pipe(map(res => res.myCondition ? res : null),
        repeatWhen(res => retries-- > 0 ? of(res) : res), 
        catchError((error: HttpErrorResponse) => (error))

让我们对操作员的描述进行分解:

返回使用 完全的例外。如果源可观测调用complete(1),则 方法将发送到从通知程序返回的可观察对象。如果 可观察调用完成或错误(2),则此方法将调用 子订阅已完成或有错误。否则,这种方法 将重新订阅可观察的源(3)

(1):我可以假设源可观测的
this.http.get()
将在get请求完成后调用complete,对吗?因此,当操作员最终被通知/调用时,
会重复

(2):如果您达到了允许的重试次数,那么您就不想再重试了,对吗?因此,您必须从
repeatWhen

(3):否则,只需返回一个发出单个值的可观察对象,以指示您要重试(重新订阅)get请求

因此,您可能正在寻求以下改进(编辑:请参见下面的“为什么这个答案是错误的”):

(*)请注意,我还将
map
操作符替换为
mergeMap
,以防止流发出
null
值。如果您的条件不满足,它将返回一个空的可观测值,以便不发出任何信息

编辑:

好吧,我错了。在rxjs游乐场中尝试上述代码后,我注意到,
repeatWhen
操作符没有为源可观察到的每个值调用匿名函数。取而代之的是,anonymous函数只调用一次,它必须返回一个基于作为参数接收的可观察通知的可观察值:

let finished = false;
return this.http.get()
   .pipe(
        mergeMap(res => {
            finished = retries-- <= 0 || res.myCondition;
            return finished ? of(res) : EMPTY),
        }
        repeatWhen((notifications) =>
            notifications.pipe(
                takeWhile(() => !finished)
            )
        ),
        ...
   );
let finished=false;
返回这个.http.get()
.烟斗(
合并映射(res=>{
完成=重试--
烟斗(
takeWhile(()=>!完成)
)
),
...
);

奇怪的是,
通知
主体对于源可观察到的每个发射(
http.get
),除了
未定义
)之外,不会发射任何东西它只提供了
未定义的
。因此我们可以强制改变
完成的
标志来控制
repeatWhen
操作符。我在另一个问题中找到了这个解决方法,所以:

我更新了我的答案,因为我在第一次尝试中做了一些错误的假设:-)@kruschild非常感谢您的回答!它有效,而且这是一个很好的解释!!!如果你不介意,请将empty()更新为empty,因为empty()是空的从rxjs 6+开始就被弃用了。我注意到repeatWhen是第一个被击中的东西,这是出乎意料的。关于它为什么会这样做有什么想法吗?谢谢@Farnoosh,我不知道它被弃用了。我更新了我的答案。总是很乐意帮助。
let finished = false;
return this.http.get()
   .pipe(
        mergeMap(res => {
            finished = retries-- <= 0 || res.myCondition;
            return finished ? of(res) : EMPTY),
        }
        repeatWhen((notifications) =>
            notifications.pipe(
                takeWhile(() => !finished)
            )
        ),
        ...
   );