RxJS测试两个流的相等性,无论顺序如何

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

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 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,我还没有为这个操作符编写任何测试,所以我不能完全确定我已经涵盖了所有的边缘情况。

在比较之前对这两种情况进行排序?我上面的示例是伪代码。在实际情况下,我不知道第一个可观测值的顺序,也不知道第二个可观测值的顺序。我所关心的是,在完成时,这些值是相等的。