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$
)上使用RxJSshareReplay()
操作符在其他两个可观察(初学者课程$
和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));