Error handling 捕获合并的可观察对象上的错误,并在RxJS中继续其他对象

Error handling 捕获合并的可观察对象上的错误,并在RxJS中继续其他对象,error-handling,merge,rxjs,observable,Error Handling,Merge,Rxjs,Observable,用例: 我正在尝试使用RxJS在javascript中实现一个保存过程。我有一个名为example set的方法,在其中,我希望首先将对象保存到本地数据库中,然后再将其发送到服务器。例如,我有以下代码: set({obj,group='main'}){ //告诉LocalDB以适当的名称和组(适当的表)存储obj const storageObservable=this.parealDB.storage.set(this.name,group,{…obj,status:0});//状态0表示需要

用例: 我正在尝试使用RxJS在javascript中实现一个保存过程。我有一个名为example set的方法,在其中,我希望首先将对象保存到本地数据库中,然后再将其发送到服务器。例如,我有以下代码:

set({obj,group='main'}){
//告诉LocalDB以适当的名称和组(适当的表)存储obj
const storageObservable=this.parealDB.storage.set(this.name,group,{…obj,status:0});//状态0表示需要将记录同步(发送)到服务器
//告诉WebClient将obj同步到适当的名称和组(适当的表)
const webclientObservable=this.parealDB.webclient.set(this.name,group,obj);//尝试发送到服务器,然后在localDB上设置status=1/此请求不应失败
存储管(
catchError(错误=>of({
操作:“存储错误”,
数据:错误,
}))
);
webclientObservable.pipe(
点击(result=>this.parealDB.storage.set(this.name,group,{u id:obj.\u id,status:1})),
catchError(错误=>of({
操作:“WEBCLIENT\u错误”,
数据:错误,
}))
);
返回合并(storageObservable、webclientObservable);
}
我想在set方法之外返回一个合并的可观测值,在捕获每个内部作业的错误的同时,也继续其他作业

问题: 我已经用一些测试观测来测试这个想法。首先,看一下示例:

//每2.5秒发射一次
第一个常数=间隔(200)。管道(
映射(val=>“”+val+“A”),
采取(3)
);
//每2秒发射一次
常数秒=间隔(100)。管道(
mergeMap(val=>{if(val===1)返回投掷者('salam');返回('''+val+'B');}),
//点击(val=>console.log('tapped',val)),
采取(3)
)
//.烟斗(
//OneRorResumeNext(),
// )
//每1.5秒发射一次
常数三=间隔(300)。管道(
映射(val=>val+“C”),
采取(3)
);
合并(第一、第二、第三)
//.烟斗(
//catchError(error=>of(error)),
// )
.订阅({
下一步:console.log,
错误:console.error,
complete:()=>console.log('completed')
});
现在,当第二个失败时,它会中断整个作业,输出如下所示:

0 B
0 A
salam // (error)
如果我尝试在合并的observable上取消catch error管道的注释,它会将salam作为一个正常输出,并完成作业,但仍然会使其短路:

0 B
0 A
salam
completed
我找到的最好的解决方案是在合并它们之前,对每个内部可观察对象进行下一步处理。因此,在第二个可观察对象上取消对所述运算符的注释(这导致了问题)将导致此输出:

0 B
0 A
0 C
1 A
2 A
1 C
2 C
completed
它非常接近于我正在搜索的内容,但超出设置的方法,我无法捕获错误(侦听错误)

问题:
那么,我是否错过了使用RxJS可观测数据,或者是否有更好的方法来处理这种情况?

您可以使用repeat()操作符来保持流的活动状态,但请小心使用,您必须确保源流是热可观测数据,否则可能会遇到无限循环

streamA.pipe(
catch(e=>of(e)),
repeat())

我不明白你想要发生什么我想要这样:例如,如果B失败,A和C继续发布,并进行下一次回调,同时还可以将B的错误通知订阅者。在RxJS中,链最多可以发出一个
错误
通知,然后该链被释放。因此,您不能在收到两个
错误
s的通知后,再接收带有正确数据的
next
。我想你唯一的选择是用
catchError()
将每个
error
转换成
next
,谢谢@martin我在第一个例子中测试过这个,我想这可能是一个不好的做法。使用
catchError
包装错误在eg.NgRx效果中非常常见,我认为Angular docs也在使用这个。通常没有别的办法。也许你可以为每个输入创建多个具有中间主题的订阅,但这将是不必要的复杂。很好的提示@FanCheung,但这与我的问题无关。如果我在其中一个流上捕获到错误,那么错误将不会传播到合并流,如果在合并流上执行此操作,则在捕获错误后将崩溃。您可以对合并流使用相同的模式,将其视为失败的重新订阅。在这种情况下,我不同意您的看法。因为每个子流的作业都是独立运行的,当合并的流抛出一个失败流的错误时,其他流仍然是活动的(我不希望,在某些情况下不能杀死它们),而合并的流立即停止。您想要实现什么?如果你担心的话,你甚至可以考虑使用重复操作符。