Rxjs Subject.asObservable()不起作用,但是BehaviorSubject有效...为什么?

时间:2018-06-27 18:18:46

标签: angular rxjs subject behaviorsubject

我已经签出了此https://github.com/angular/angular/issues/12129 但我没有任何解决方案...

Angular 2.0.1 AsyncPipe doesn't work with Rx Subject

  

这里的解决方案是在组件中创建一个可观察的变量

我有哪些但仍无法正常工作...不确定我将UserStateService中的Subject切换为BehaviorSubject为何一切正常...

注意: 根app.module.ts上同时提供了UserDataService和UsersStateService。

user-data.service.ts->发出我在组件中调用的http请求

fetchUsers():void{
   this.httpClient.get<User[]>(this.apiUrl, {
  observe: 'body',
  responseType: 'json'
})
.subscribe( (response: User[])=>{
    this.usersStateService.setUsersList(response);  <-- set to local state service

  });

}

users-state.service.ts

userListState = new Subject<User[]>();   <-- Change this to BehaviorSubject<User[]>([])  everything works!

setUsersList(users: User[]):void {
  this.userListState.next(users.slice());
}

getUsersListState():Observable<User[]>{
   return this.userListState.asObservable();
}

component.ts

 users: Observable<User[]>;

 ngOnInit() {

 if(this.usersStateService.hasUserList()){

  this.users = this.usersStateService.getUsersListState();  -|
                                                             |
  // this.usersStateService.getUsersListState()              |
  //   .subscribe((x) => console.log(x));                   -| <-- This does not output for some reason IF Subject... BehaviorSubject works..
}else{
  console.log("No data in local stat -> fetch") . <-- This works either with Subject or BehaviorSubject
  this.userData.fetchUsers();
  this.users = this.usersStateService.getUsersListState();
}

}

HTML

<li *ngFor="let u of (users | async)">u.name</li>

请提供任何见解,谢谢!!

1 个答案:

答案 0 :(得分:2)

主题不保存任何数据,它只是调用使用该值订阅它的任何数据。 BehaviorSubject保存数据,并且每次调用发出它都会替换当前数据。

当您尝试通过服务控制台日志时,用户列表:
使用主题时,它不包含任何持久数据。

this.usersStateService.getUsersListState()              
 .subscribe((x) => console.log(x));  ==> would be empty 

使用BehaviorSubject 可以保存最后一个数据,也可以使用值进行初始化。

let _array = ['one','two']
let bs = new BehaviorSubject<any>(_array ).asObservable();
bs.subscribe(arr => {
 console.log(arr) // ==> Would log the _array: ['one','two']
})

因此,在您的情况下,当您尝试通过Subject获取数据时,它在第一次调用后(发出时)就不存在,而BehaviorSubject保留您的初始值,并且每次发出时,因此始终存在持久数据。
**如果每次需要多个值,则应查看ReplySubject