等待返回可观察对象的函数内的订阅结果

时间:2018-06-14 20:02:05

标签: angular rxjs observable

考虑以下功能

Go(publicRoute: boolean, token: string) {
    let rtrn = {} as aaResult;

    if (publicRoute) {
        rtrn.Authenticated = true;
    }
    else {
        if (token != "" || this.userService.Get() != null) {
            if (this.userService.Get() != null) {
                rtrn.Authenticated = true;
            }
            else {
                this._authorize(token).subscribe(res => {
                    console.log("internal subscribe");
                    console.log(res);
                    this.userService.Set(new User(res));                      
                    if (this.userService.Get() != null) {
                        rtrn.Authenticated = true;
                        rtrn.User = this.userService.Get()
                    }
                    else
                        this._authenticate();
                }
                    ,
                    error => {
                        this._authenticate();
                    }
                )
            }
        }
        else {
            this._authenticate();
        }
    }

    return (Observable.of(rtrn));
}

如果第一个iftrue,则返回数据正确无误。如果iffalse,则返回数据为{},因为该函数不会等待this._authorize的结果。如何使函数等待内部可观察的结果?

这是整个事情被调用的方式,以防万一:

this.AA.Go(this.publicRoute, this.internalToken).subscribe(res => { console.log(res) })

修改

authorize函数的代码添加到observable

private  _authorize(token: string, options?: any): Promise<User> {
    return this.http.get<User>(this.config.aa.autherizationUrl + "?token=" + token, {
        headers: this.Utils.SetRequestAppOptions(options === undefined ? {} : options),
    }).toPromise();
}

1 个答案:

答案 0 :(得分:1)

您应该考虑,因为observable是异步的,将this._authorize返回类型更改为promise。那么你可以做await this._authorize

await专门等待,直到函数完全执行,然后再继续。 Await仅适用于promises,因此您需要更改返回类型。

如果该函数是可观察的。您可以使用.toPromise()以简单的方式使其成为承诺。

修改

假设您有返回observable的方法,这应该可行。在promise上,结果存储在变量中,因此您无法订阅它。

这项工作:

import { from } from 'rxjs';

async function GoAsync(publicRoute: boolean, token: string) {
  let rtrn = {} as aaResult;

  if (publicRoute) {
      rtrn.Authenticated = true;
  }
  else {
      if (token != "" || this.userService.Get() != null) {
          if (this.userService.Get() != null) {
              rtrn.Authenticated = true;
          }
          else {
              try {
                 let res = await this._authorize(token); //wait for the response
                  console.log("internal subscribe");
                  console.log(res);
                  this.userService.Set(new User(res));
                  if (this.userService.Get() != null) {
                      rtrn.Authenticated = true
                      rtrn.User = this.userService.Get()
                  }
              }
              // avoid else's and catch, using finally.
              catch {
                  // error handle here
              }
          }
      }
      // allways perform this action, as stated in your code
      this._authenticate();
  }
  return (rtrn);
}

function Go(publicRoute: boolean, token: string) {
    return from(GoAsync(publicRoute,token))
}