组件BehaviorSubject订阅者未收到从异步http请求发出的值 [英] Component BehaviorSubject subscriber does not receive value emitted from async http request

查看:54
本文介绍了组件BehaviorSubject订阅者未收到从异步http请求发出的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解为什么这个BehaviorSubject订阅者没有收到发射的值.

I'm trying to understand why this BehaviorSubject subscriber does not receive emitted values.

在我的组件ngOnInit中,我设置了服务方法的订阅者,该服务方法返回对BehaviorSubject的引用:

In my component ngOnInit I setup a subscriber to a service method that returns a reference to a 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的下一个方法中:

In the service, I make an http request and then push the response data into the BehaviorSubject's next method:

 // 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 $)中的更改.

My understanding is that the subscriber in my component's ngOnInit should listen for changes from the BehaviorSubject reference returned from getProject (i.e. currentProjectObs$).

当ngOnInit首次运行时,它将调用getProject,并且由于getProject中的http调用是异步的,因此返回的currentProjectObs $的初始值为null.但是,一旦http get请求完成,就会调用currentProjectObs $ .next(project),并且我希望ngOnInit中的订户会收到新发出的值-但这不会发生.

When ngOnInit first runs it calls getProject and since the http call inside getProject is asynchronous currentProjectObs$ is returned with the initial value of null. But once the http get request completes, currentProjectObs$.next(project) gets invoked and, I would expect, the subscriber in ngOnInit to receive the newly emitted value - but this doesn't happen.

我想了解这里发生了什么,为什么订阅者没有收到来自http请求的异步值,以及如何解决该问题,以使其得以解决.

I'd like to understand what's going on here and why the subscriber doesn't receive the async value from the http request, and how to fix it so that it would.

推荐答案

当您使用下面的函数时,它将再次返回null值,因为它不会等待api调用.并且如果您使用的是行为主题,则可以直接从行为主题获取价值,则无需返回.

When you use below function it will again return null value because it will not wait for api call. and if you are using Behavior subject than you can directly take value from behavior subject, you not need to return it.

getProject(id: number = 0) {
  if (id) {
    this.http.get(`${this.apiUrl}/projects/${id}`)
      .subscribe(project => {
        this.currentProjectObs$.next(project);
      });
  }
  return this.currentProjectObs$;
}

您可以使用这两种类型来做到这一点.确实将其更改为类似这样的内容:

You can do it with these two types. Do Change it to Something like this :

1.不使用行为主题.

// Your Service 
getProject(id: number = 0): Observable<any> {
    if (id) {
       return this.http.get(`${this.apiUrl}/projects/${id}`)
          .pipe(map(project => {
               return project;
               // this.currentProjectObs$.next(project);
          });
    }
    return Observable.of(null);
};

// Your Component
ngOnInit() {
  this.activatedRoute.params.subscribe((data: Params)  => {
    if (data && data.id) {
      this.projectService.getProject(data.id)
        .subscribe(project => {
            console.log(project);
      });
    }
  });
}

2.与行为主题一起使用

// Your service

public currentProjectObs$ = new BehaviorSubject<IProject>(null);

getProject(id: number = 0) {
  if (id) {
    this.http.get(`${this.apiUrl}/projects/${id}`)
      .pipe(map(project => {
        this.currentProjectObs$.next(project);
      });
  }
  // return this.currentProjectObs$;
}

// Your component
this.activatedRoute.params.subscribe((data: Params)  => {
    if (data && data.id) {
      this.projectService.getProject(data.id);
    }
});

this.projectService.currentProjectObs$
   .subscribe(project => {
       if(project){
          console.log(project);
       }
})

这篇关于组件BehaviorSubject订阅者未收到从异步http请求发出的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆