我有一个角度服务和两个使用此服务的不相关组件:
服务代码:
const url = 'ws://localhost:8080
@Injectable({
provideIn: 'root',
})
export class MyService{
public subject: Subject<Status>;
constructor(wsService: WebSocketService){
this.subject = <Subject<Status>>wsService.connect(url).map(
(response: MessageEvent): Status => {
let data = JSON.parse(response.data);
return data;
}
);
}
getObs(){
return this.subject.asObservable();
}
sendMsg(msg){
this.subject.next(msg);
}
}
组件1:
@Component
.. some irrelevant code ..
constructor(private service: MyService){
this.service.getObs().subscribe( data =>
console.log('comp1');
);
console.log('comp1 - after subscribe');
}
.. some irrelevant code ..
组件2:
@Component
.. some irrelevant code ..
constructor(private service: MyService){
this.service.getObs().subscribe( data =>
console.log('comp2');
);
console.log('comp2 - after subscribe');
}
.. some irrelevant code ..
我在控制台中得到以下输出:
comp1
comp1-订阅后
comp2-订阅后
我认为我应该得到的输出:
comp1
comp1-订阅后
comp2
comp2-订阅后
谁能解释这个问题是什么?
注意:我将我的服务添加到了模块提供程序中,并得到了相同的结果。
谢谢。
这是webSocketService的代码:https://github.com/elliotforbes/ng-chat/blob/master/src/app/common/services/websocket.service.ts
您应该控制自己的主题,而不是piggy依WebSocketService.connect
并假设您将获得期望的行为。
从链接到您发布的WebSocketService
的源代码,我们看到它是一个简单的主题。您想要的功能-在订阅时发出一个值(假设存在)-由ReplaySubject
提供。
您应该声明一个本地ReplaySubject
,这是您的组件将预订的。然后,您将订阅您的WebSocketService
。来自WebSocketService
的任何响应都将映射到一个状态,然后发送到您的本地主题。
const url = 'ws://localhost:8080
@Injectable({
provideIn: 'root',
})
export class MyService{
// Declare local ReplaySubject that emits the last value upon subscription
private subject: Subject<Status> = new ReplaySubject<Status>(1);
constructor(wsService: WebSocketService) {
// Subscribe to the web socket service.
// Subscribing in constructors is fairly bad practice,
// although you can get away with it in singleton services
wsService.connect(url).pipe(
// map responses to statuses
map((response: MessageEvent): Status => {
let data = JSON.parse(response.data);
return data;
})
).subscribe((status: Status) => {
// send the status to all subscribers
this.subject.next(status);
});
}
getObs(): Observable<Status> {
return this.subject.asObservable();
}
sendMsg(msg): void {
this.subject.next(msg);
}
}