与RxJs完全异步返回

时间:2018-05-02 10:19:00

标签: angular asynchronous rxjs observable

我尝试从使用rxjs调用API的函数返回值(字符串)。变量必须在observable的complete子句中返回。

这是代码:

getToken(): any {
    let token = '';

    this.meService.getMe().subscribe(data => {},
      err => {
        let headers = new HttpHeaders();
        headers = headers.set('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8').set(InterceptorSkipHeader, '');
        this.http.post(Configs.heroku + 'https://login.microsoftonline.com/common/oauth2/v2.0/token', 'grant_type=authorization_code&code=' + localStorage.getItem('refresh') + '&client_id=' + Configs.appId + '&redirect_uri=http://localhost:4200/redirect&' + 'client_secret=lkcqTNT730}zyoVLOX45)|;', {headers: headers}).subscribe(data => {
          localStorage.setItem('access', data['access_token']);
          token = localStorage.getItem('access');
        });
      },
      () => {
        return localStorage.getItem('access');
      });
  }

正如您所看到的:我试图在complete子句中返回一个变量。但是,它永远不会返回变量。当我在调用函数中打印出来时,它只是说未定义。任何解决方案?

提前致谢!

编辑:

这是调用函数的部分:

console.log(auth.getToken());
    req = req.clone({
      setHeaders: {
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': 'Bearer ' + auth.getToken()
      }
    });

1 个答案:

答案 0 :(得分:-1)

我会试着向你解释发生了什么。

  1. 你的getToken函数没有返回任何内容。因此在打印时你会得到不确定的。
  2. 当您订阅一个observable时,您有3个可能的参数:
    • next:每次在你的observable中获得“tick”时执行。
    • 错误:发生错误时执行。
    • complete:在observable完成时执行。
  3. 在任何这些情况下,您都会传递一个必须在每个事件发生时执行的回调。由于您在这些回调中返回,因此您不返回getToken方法,而是返回subscribe方法中调用的函数。想象一下订阅方法的可能实现:

    subscribe(nextCB, errorCB, completeCB){
        ...
        if(completed) {
            completeCB();
        }
    }
    

    如您所见,未分配或返回完整回调的返回值。 您的案例有多种解决方案/替代方案。您可以使用一些映射返回observable本身(this.meService.getMe()),然后在任何地方订阅它,或者只需在完整的回调中运行代码即可。 但IMO最好花点时间寻找javascript一般闭包和异步概念。