Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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
RxJS:即使在源可观察对象上使用'shareReplay()','throwError()',也会对每个可观察对象分别执行_Rxjs_Rxjs6_Rxjs Pipeable Operators - Fatal编程技术网

RxJS:即使在源可观察对象上使用'shareReplay()','throwError()',也会对每个可观察对象分别执行

RxJS:即使在源可观察对象上使用'shareReplay()','throwError()',也会对每个可观察对象分别执行,rxjs,rxjs6,rxjs-pipeable-operators,Rxjs,Rxjs6,Rxjs Pipeable Operators,我在一个可观察(courses$)上使用RxJSshareReplay()操作符在其他两个可观察(初学者课程$和advancedCourses$)之间共享可观察流。它工作得很好,成功后两个观察对象之间共享单个API调用响应 但是,当涉及到错误时,这些可观察到的不共享错误,并且错误会在浏览器控制台中被抛出两次。操作员是否也共享错误?这是故意的行为吗 consthttp$=createHttpObservable('/api/courses'); const courses$=http$ .烟斗(

我在一个可观察(
courses$
)上使用RxJS
shareReplay()
操作符在其他两个可观察(
初学者课程$
advancedCourses$
)之间共享可观察流。它工作得很好,成功后两个观察对象之间共享单个API调用响应

但是,当涉及到错误时,这些可观察到的不共享错误,并且错误会在浏览器控制台中被抛出两次。操作员是否也共享错误?这是故意的行为吗

consthttp$=createHttpObservable('/api/courses');
const courses$=http$
.烟斗(
映射(res=>res['payload']),
shareReplay(),
catchError(err=>{
回程抛掷器(err);
})
);
这个。初学者课程$=课程$
.烟斗(
地图(课程=>课程
.filter(course=>course.category==“初学者”);
此.advancedCourses$=课程$
.烟斗(
地图(课程=>课程
.filter(course=>course.category=='ADVANCED'));
}

当可观察对象抛出错误时,这是预期的行为,shareReplay()将尝试重新订阅/重新执行源代码

你可以试着验证一下

const a=defer(()=>{
  console.log('run')
  return throwError(new Error('Error'))
}).pipe(shareReplay())

a.subscribe(console.log,console.error,()=>console.log('complete'))
a.subscribe(console.log,console.error,()=>console.log('complete'))

如果希望observable共享错误而不再次执行
使用
publishReplay(1),refCount()
而不是我认为这是预期的行为,有点出乎意料的是,您得到了两个不同的错误

shareReplay
在数据使用者和数据生产者之间放置一个
ReplaySubject
。当错误通知到达时,正在使用的
ReplaySubject
将向所有注册订户发送相同的错误通知:

错误(错误:任意){
如果(本节已结束){
抛出新的ObjectUnsubscribedError();
}
this.hasrerror=true;
this.thrownError=err;
this.isStopped=true;
const{observators}=this;
const len=长度;
const copy=observators.slice();
for(设i=0;i

但是当使用
shareReplay
时,如果出现错误,当新订户将要订阅时,正在使用的
ReplaySubject
将被另一个替换。如果说它正在被替换,这还需要重新订阅源代码

因此,我认为所有订阅者都应该收到相同的错误通知,只要他们已经是
ReplaySubject
订阅者列表的一部分。否则,当新的订户进来时,源将被重新订阅


您可以做的是防止
ReplaySubject
接收错误通知并允许其订阅者按原样接收,即使用
物化
非物化
操作符:

const courses$=http$
.烟斗(
materialize(),//所有内容都作为“下一个”通知
映射(res=>res['payload']),
shareReplay(),
去物质化()//返回到原始事件
);
使用这种方法,如果注册的订阅者收到错误通知,它将被取消订阅,这意味着它也将从
ReplaySubject
的订阅者列表中删除。但是
ReplaySubject
仍将存在,并且不会在后续订阅服务器上被替换


此外,我认为这是相当多余的:

catchError(err=>throwError(err));