繁体   English   中英

Angular 在返回数据之前等待订阅完成

[英]Angular wait for subscribe to finish before return data

嗨,有一个非常简单的函数可以调用端点来检索我的用户,我在标题中使用它来显示连接的用户,但不想在每次呈现标题时都调用端点。

所以我正在尝试这样的事情:

public getUser(): User {
    if (!this.user) {
     
      this.http.get<User>(environment.apiRoot + '/me').subscribe(res => {
        this.setUser(res);
        return this.user.value;
      }, err => {

      });
    } else {
      return this.user.value;
    }
  }

使用setUser函数:

public setUser(u: User): void {
    if (!this.user) {
      this.user = new BehaviorSubject(u);
    } else {
      this.user.next(u);
    }
  }

BehaviorSubject : private user: BehaviorSubject<User>;

在我的头组件中,我在ngOnInit这样称呼它:

this.user = this.appState.getUser();
console.log(this.user);

但是console.log里面的user一直是undefined,为什么不等待getUser函数里面的订阅呢?

您有一个异步函数,您正在使用混合反应式和命令式编程调用该函数。 当涉及到异步函数时,你应该坚持使用反应式方法,不要试图确定某个代码何时完成,而只是等待它完成,然后随后调用回调或负责的处理程序。

在您的代码中, getUser()函数是一个async函数,因为您有内部http.get()调用。 http.get()将返回一个Observable ,您在函数中不必要地subscribe它。 你应该做的是从函数返回内部observable ,并在你真正需要它的地方subscribe

我们可以像下面这样重写你的getUser函数(注意,不需要命令setUser函数)

public getUser(): Observable<User> {
    return this.http.get<User>(environment.apiRoot + '/me');
}

并在您的外部范围内订阅它,例如

this.appState.getUser().subscribe(user => {
    console.log(user)
});

更进一步,这也使在模板中使用 observable 变得更容易。

假设您将返回的 observable 分配给变量user$ ,您甚至不必订阅它!

只要让用户喜欢

this.user$ = this.appState.getUser();

获取您的 observable,然后在您的模板中使用async管道让 Angular 自动订阅和取消订阅。

<span>Hello, my name is {{user$ | async}}!</span>

如果您希望getUser函数等待订阅完成,则必须返回 observable。 然后将.subscribe()this.appState.getUser()

public getUser(): Observable<User> {
    if (!this.user) {
      return this.http.get<User>(environment.apiRoot + '/me').pipe(map(res => {
        this.setUser(res);
        return this.user.value;
      }, err => {

      }));
    } else {
      return of(this.user.value);
    }
  }

this.appState.getUser().subscribe(user => {
    console.log(user)
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM