如何在角度5中进行同步调用?

时间:2017-12-02 07:40:58

标签: angular service angular-services angular-components angular5

所以,我试图解决这个问题。但是,不知怎的,我无法这样做,可能是因为角度5缺乏知识。 这是我的服务:

GetCurrentUserData(): Observable<ResponseData> {
    return this.http.get<ResponseData>(ApplicationURLS.GetCurrentUserInformation)
        .map(response => {
            return response;
        });
    //.catch(error => this.handleError(error));
}

这是我的组成部分:

public GetCurrentUserInformation(): any {

        return this.loginService.GetCurrentUserData().subscribe(data => { return data; });
    }

我在这里尝试访问数据:

ngAfterViewInit() {
        debugger;                
        this.responseData = this.GetCurrentUserInformation();
        if (this.responseData.code != responseCodes.success) {
            this.googleInit();
        }

    }

当我检查this.responseData时,它总是返回此而不是我想要的数据: enter image description here

我只想进行同步通话,以便立即获取数据。

我也尝试在服务中使用do(),但返回的do()不是函数。

5 个答案:

答案 0 :(得分:5)

订阅GetCurrentUserData() http呼叫是异步的(每个浏览器api调用都是异步的,因为javascript引擎在单个线程中运行(google for browser event loop for more,这不是一个角度问题))< / p>

this.GetCurrentUserInformation().subscribe((data: ResponseData) => {
        if (this.responseData.code != responseCodes.success) {
            this.googleInit();
        }
});

答案 1 :(得分:2)

异步函数不能同步调用,因为它们是异步的。

subscribe通常不应该在预期被链接的方法中执行。即使它应该,也应该从方法返回一个可观察的而不是订阅(订阅可以另外保存,以便在销毁时取消订阅)。

GetCurrentUserInformation方法是多余的,因为它只是服务调用的包装器。代码可以重构为:

ngAfterViewInit() {
    this.loginService.GetCurrentUserData().subscribe(data => {
        this.responseData = data;
        if (this.responseData.code != responseCodes.success) {
            this.googleInit();
        }
    });
}

答案 2 :(得分:2)

这可以通过使用async/await??

来简化
public GetCurrentUserInformation(): Promise<any>{
    return this.loginService.GetCurrentUserData().toPromise()
}

ngAfterViewInit

async ngAfterViewInit() {    
        this.responseData = await this.GetCurrentUserInformation(); // ?‍♂️ 
        if (this.responseData.code != responseCodes.success) {
            this.googleInit();
        }
    }

答案 3 :(得分:1)

确保在处理响应之前执行异步调用的另一种方法是使用ReactiveX中的Observable.forkJoin()。

Observable.forkJoin(
    this.http.get('/links.json').map((response:Response) => response.json()),
    this.http.get('/bookmarks.json').map((response:Response) => response.json())
).subscribe(
    data => {
      this.links = data[0]
      this.bookmarks = data[1]
    },
    error => console.error(error)
);
所有HTTP请求成功完成后,

onNext处理程序只执行一次。

必需的导入:

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

这里有link to the article更详细地描述它。

答案 4 :(得分:0)

没有直接的方法可以进行同步调用,但是您可以执行以下过程(此代码以7号角编写)。

import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';

export class SampleComponent implements OnInit {
  Request1result:Object;
  Request2result:Object;

  constructor(private http:HttpClient) { }

   ngOnInit() 
   {
    this.http.get("URL1").subscribe((res)=>{
      this.Request1result=res;
      this.after1(); // execution will move to next request only when first is done.
    });
   }
  after1()
  {
    this.http.get("URL2").subscribe((res)=>{
      this.Request2result=res;
      this.after2(); // execution will move to the rest of the code only when both the requests are done.
    });
  }
  after2()
    {
    // rest of the code.
    console.log(this.Request1result);
    console.log(this.Request2result);

    }

}