我试图理解为什么这个BehaviorSubject订阅者不接收发出的值 .
在我的组件ngOnInit中,我将订阅服务器设置为一个返回对BehaviorSubject的引用的服务方法:
// project-detail.component.ts
ngOnInit() {
this.activatedRoute.params.subscribe((data: Params) => {
if (data && data.id) {
this.projectService.getProject(data.id).subscribe(project => {
console.log(project);
});
}
});
}
在服务中,我发出一个http请求,然后将响应数据推送到BehaviorSubject的下一个方法:
// project.service.ts
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable()
export class ProjectService {
private apiUrl = envLocal.apiJsonServerUrl;
private currentProjectObs$ = new BehaviorSubject<IProject>(null);
constructor(private http: HttpClient) {
}
getProject(id: number = 0) {
if (id) {
this.http.get(`${this.apiUrl}/projects/${id}`)
.subscribe(project => {
this.currentProjectObs$.next(project);
});
}
return this.currentProjectObs$;
}
我的理解是我的组件的ngOnInit中的订阅者应该监听从getProject返回的BehaviorSubject引用的更改(即currentProjectObs $) .
当ngOnInit首次运行时,它调用getProject,并且由于getProject内的http调用是异步的,因此返回currentProjectObs $,初始值为null . 但是一旦http get请求完成,currentProjectObs $ .next(项目)就会被调用,我希望,ngOnInit中的订阅者可以接收新发出的值 - 但这不会发生 .
我想了解这里发生了什么以及为什么订阅者没有从http请求中收到异步值,以及如何修复它以便它 .
2 回答
当你使用下面的函数时,它将再次返回null值,因为它不会等待api调用 . 如果您使用的是
Behavior subject
,则可以直接从行为主题中获取值,您无需返回它 .您可以使用这两种类型来完成 . 把它改成这样的东西:
1. Without use of behavior subject.
2. Use With Behavior subject
我认为您的代码可以简化一下:
在您的服务中:
当您确实需要数据执行某些操作时,您应该只在最后订阅 . 使用Rxjs运算符,数据可以在一个可观察对象之间流动 . 切换映射订阅第一个observable并返回我们在结尾处订阅的另一个 .
如果这对您有用,请告诉我 .