Design patterns Observer模式设计与RXJS库
我是RXJS库的新手,试图弄清楚如何正确地使用可观察对象和主题。 我试图与模式设计观察家进行比较。Design patterns Observer模式设计与RXJS库,design-patterns,rxjs,observable,observer-pattern,rxjs-observables,Design Patterns,Rxjs,Observable,Observer Pattern,Rxjs Observables,我是RXJS库的新手,试图弄清楚如何正确地使用可观察对象和主题。 我试图与模式设计观察家进行比较。 在某一点上,我有一个问题,如果RXJS库中的Observable实例是Observator模式设计的一个特例?根据定义,Observable是一个随时间发射数据的实体。这听起来有点模糊,同时也很有趣 在我看来,所有RxJS的魔力都是通过链表实现的 每当您使用newobservable(subscriber=>{})创建Observable时,您就是在定义源,或链表的头节点。另外,您是否曾经想知道为
在某一点上,我有一个问题,如果RXJS库中的Observable实例是Observator模式设计的一个特例?根据定义,Observable是一个随时间发射数据的实体。这听起来有点模糊,同时也很有趣 在我看来,所有RxJS的魔力都是通过链表实现的 每当您使用
newobservable(subscriber=>{})
创建Observable
时,您就是在定义源,或链表的头节点。另外,您是否曾经想知道为什么该参数被称为subscriber
或observer
?我也会尝试分享我的观点
主链接列表是在以下人员的帮助下创建的:
管道(…操作:运算符功能:
受保护升降机(操作员?:操作员):可观察{
const observable=新的observable();
可观测源=此;
可观察。操作员=操作员;
可观测收益;
}
正如您所知,在RxJS中有许多运算符。运算符是一个函数,它返回另一个函数,该函数的参数是可观察的
(类型为T
),其返回值也是可观察的
(类型为R
)
例如:
导出函数映射(项目:(值:T,索引:number)=>R,thisArg?:any):运算符函数{
返回函数映射操作(来源:可观察):可观察{
if(项目类型!==‘功能’){
throw new TypeError('参数不是函数。是否正在查找'mapTo()`?');
}
返回升降机(来源,新地图操作员(项目,thisArg));
};
}
所以,当你
const src$=新的可观察对象(s=>/*…*/)
.烟斗(
映射(/*…*/)
)
会发生一些事情:
- 首先,它将创建可观察的
实例;提供的回调(在本例中为s=>…
)将存储在属性中
- 调用
pipe()
;它将返回fns[0]
,在本例中为mapOperation
函数
mapOperation
将以Observable
实例作为其参数(从pipeFromArray(operations)(this)
)调用;调用时,它将调用source.lift(new MapOperator(project,thisArg));
;Observable.lift()
是将节点添加到此链接列表的部分;如您所见,是一个节点(除了HEAD
)之外)保存源代码和代表它的操作符
当您订阅src$
时,将基于此列表创建另一个。在此列表中,每个节点都将是订户
。此列表的创建基于以下事实:每个操作员
导出接口操作符{
呼叫(订户:订户,来源:任意):拆卸逻辑;
}
:
导出类MapOperator实现运算符{
构造函数(私有项目:(值:T,索引:number)=>R,私有thisArg:any){
}
呼叫(订户:订户,来源:任意):任意{
返回source.subscribe(新的MapSubscriber(subscriber,this.project,this.thisArg));
}
}
Subscriber
节点之间的关系在Observable.subscribe()中建立
在这种情况下,newobservable(s=>…)
(上例)中的s
参数将是MapSubscriber
我似乎偏离了这个问题,但通过以上解释,我想证明这里没有太多的Observer
模式
此模式可通过主题
实现,该主题:
export类Subject扩展了可观察的实现类SubscriptionLike{}
这意味着您可以使用Subject.pipe(…)
和Subject.subscribe(subscriber)
。Subject
要实现此模式,需要有一个自定义方法:
\u订阅(订阅方:订阅方):订阅{
如果(本节已结束){
抛出新的ObjectUnsubscribedError();
}else if(this.hasError){
订户.error(this.thrownError);
返回Subscription.EMPTY;
}else if(this.isStopped){
subscriber.complete();
返回Subscription.EMPTY;
}否则{
// !!!
this.observators.push(订户);
返回新的SubjectSubscription(此,订户);
}
}
如您所见,Subject
类跟踪其观察者(订阅者),以便在发出值时,其所有观察者都将接收该值:
next(值:T){
如果(本节已结束){
抛出新的ObjectUnsubscribedError();
}
如果(!this.isStopped){
const{observators}=this;
const len=长度;
const copy=observators.slice();
for(设i=0;i
作为一个侧节点,主题
也可以充当订户
,因此您不必一直手动调用主题。{下一步,错误,完成}()
。您可以使用类似的方法实现这一点
src$.pipe(主观性);