RxJS测试两个流的相等性,无论顺序如何
RxJS提供sequenceEqual操作符来按顺序比较两个流。不管顺序如何,我们如何测试两个流的相等性 伪代码:RxJS测试两个流的相等性,无论顺序如何,rxjs,Rxjs,RxJS提供sequenceEqual操作符来按顺序比较两个流。不管顺序如何,我们如何测试两个流的相等性 伪代码: //how do we implement sequenceEqualUnordered? from([1,2,3]).pipe(sequenceEqualUnordered(from([3,2,1]))).subscribe((eq) => console.log("Eq should be true because both observables contain
//how do we implement sequenceEqualUnordered?
from([1,2,3]).pipe(sequenceEqualUnordered(from([3,2,1]))).subscribe((eq) =>
console.log("Eq should be true because both observables contain the same values")
)
在我的特定用例中,我需要等到某一组值被发出或出错,但我不在乎它们以什么顺序发出。我只关心每一个感兴趣的价值被释放一次 我的第一个想法。在这两个页面上使用
toArray
,然后将它们一起使用zip
最后对结果进行排序和比较?以下是我的解决方案:
import{Observable,OperatorFunction,Subscription}来自'rxjs';
导出函数序列equalUndered(compareTo:Observable,comparator?:(a:T,b:T)=>number):运算符函数{
返回(来源:可观察)=>新可观察(观察者=>{
常量sourceValues:T[]=[];
常量目标值:T[]=[];
设sourceCompleted=false;
让destinationCompleted=false;
函数onComplete(){
if(sourceCompleted&&destinationCompleted){
if(sourceValues.length!==destinationValues.length){
发射(假);
回来
}
sourceValues.sort(比较器);
destinationValues.sort(比较器);
emit(JSON.stringify(sourceValues)==JSON.stringify(destinationValues));
}
}
函数emit(值:布尔){
下一步(值);
observer.complete();
}
const subscriptions=新订阅();
订阅。添加(source.subscribe)({
下一步:下一步=>sourceValues.push(下一步),
错误:error=>observer.error(错误),
完成:()=>{
sourceCompleted=true;
onComplete();
}
}));
subscriptions.add(compareTo.subscripte({
next:next=>destinationValues.push(下一步),
错误:error=>observer.error(错误),
完成:()=>{
destinationCompleted=真;
onComplete();
}
}));
return()=>subscriptions.unsubscripte();
});
}
由于许多RxJS运算符都有一些输入参数,并且都返回函数,SequenceEqualUndered
也有一些输入参数(大部分与Rx的sequenceEqual
运算符相同),并返回函数。此返回函数的可观察
类型为源
类型,返回类型为可观察
创建一个新的可观察对象,它将发出布尔值
正是您所需要的。您基本上希望从source
和compareTo
可观察对象收集所有值(并将它们存储到sourceValues
和destinationValues
数组)。为此,您需要订阅source
和compareTo
可观察对象。但是,为了能够处理订阅,必须创建subscriptions
对象。创建对源的新订阅和比较到时,只需将这些订阅添加到订阅
对象
订阅其中任何一个时,将发出的值收集到next
处理程序中相应的sourceValues
或destinationValues
数组中。如果发生任何错误,请将其传播到错误处理程序中的观察者。在complete
处理程序中,设置相应的sourceCompleted
或destinationCompleted
标志,以指示哪个可观察对象已完成
然后,在onComplete
中检查它们是否都已完成,如果都已完成,则比较发出的值并发出相应的布尔值。如果sourceValues
和destinationValues
数组的长度不相同,则它们不能相等,因此发出false
。之后,基本上对数组进行排序,然后对两个数组进行排序
发出时,同时发出值和完成
通知
此外,传递给新可观察
的函数返回值应为取消订阅
函数。基本上,当有人从新的可观察对象
取消订阅时,它也应该同时从源
和比较对象
取消订阅,这是通过调用()=>订阅。unsubscribe()
完成的<代码>订阅。取消订阅()
将取消订阅添加的所有订阅
TBH,我还没有为这个操作符编写任何测试,所以我不能完全确定我已经涵盖了所有的边缘情况。在比较之前对这两种情况进行排序?我上面的示例是伪代码。在实际情况下,我不知道第一个可观测值的顺序,也不知道第二个可观测值的顺序。我所关心的是,在完成时,这些值是相等的。