2016-12-27 46 views
-2

我是新来Angular 2.我的应用程序有一个配置文件列出所有的API网址。如何排队两个observable?

我创建了一个定位器服务来加载config.json。其他服务使用此服务来获取其特定网址。

@Injectable() 
export class LocatorService { 
    private config: any; 
    private loadConfig: Promise<any>; 
    constructor(private _http: Http) { 
     this.loadConfig = this._http.get('config/config.json') 
       .map(res => this.config = res.json()).toPromise(); 
    } 

    public getConfig() { 
     return this.loadConfig.then(() => this.config); 
    } 
} 

我有这个其他服务发送一个HTTP请求到一个URL。此服务从定位器服务获取URL。

@Injectable() 
export class OtherService { 
    private _data: any; 
    private url: string; 
    constructor(private _http: Http, private locatorService: LocatorService) { 
     this.geturl(); 
    } 

    public loadData(): model[] { 
     this.geturl().then(() => this._http.get() 
        .map(res => this._data = res.json()) 
        .catch(error => 
        Observable.throw(error.json().error || 'Server error')) 
        .subscribe(t => this._data = t.json()); 

     return this._data; 
    } 

    private geturl() { 
     return this.locatorService.getConfig().then(t => { 
     this.url = t.serviceUrl; 
     console.log(this.url); 
     }); 
    } 
} 

我的组件调用此loadData n获取所需的数据。我如何实现相同?

我不是很清楚如何等待配置url被加载然后发送http请求并返回数据。

请帮忙。

+0

在这里使用承诺有什么意义?这两个请求实际上都是可观察的。而且你做错了什么,因为上面的代码应该导致顺序请求。请提供[MCVE](http://stackoverflow.com/help/mcve)来复制这个问题,一个plunk会有所帮助。 – estus

回答

0

您不需要使用Promise这个意思then不需要使用getConfig功能LocatorService。做如下修改,并确保你有一个实例在尤尔应用LocatorService并重新进行检查:

// LocatorService

@Injectable() 
export class LocatorService { 
    private config: any = null; 

    constructor(private _http: Http) { 
     if (this.config === null) { 
      this._http.get('config/config.json') 
       .map(res => res.json()).subscribe(res => { 
       this.config = res; 
       }); 
     } 
    } 

    public getConfig() { 
     return this.config; 
    } 
} 

// OtherService

@Injectable() 
export class OtherService { 
    private _data: any; 
    private url: string; 

    constructor(private _http: Http, private locatorService: LocatorService) { 
     this.url = this.locatorService.getConfig(); 
    } 

    public loadData(): model[] { 
     return this._http.get(this.url.serviceUrl) 
        .map(res => this._data = res.json()) 
        .catch(error => 
        Observable.throw(error.json().error || 'Server error'));   
    } 

} 
+0

不,它不起作用。 getConfig不会等待http请求完成。 – Akanksha

+1

上面的代码对原始代码没有任何好处。它并行运行请求,'if(this.config === null)'check是无用的,因为每个服务实例只能运行一次构造函数。 – estus

0

你可以用它做这样:

@Injectable() 
export class LocatorService { 
    private loadConfig: Promise<any>; 
    constructor(private _http: Http) { 
     this.loadConfig = this._http.get('config/config.json') 
       .map(res => this.config = res.json()).toPromise(); 
    } 

    public getConfig() { 
     return this.loadConfig; 
    } 
} 

@Injectable() 
export class OtherService { 
    private _data: any; 
    constructor(private _http: Http, private locatorService: LocatorService) { 
    } 

    public loadData() { 
     Observable.from(this.locatorService.getConfig()) 
      .switchMap((config) => this._http.get(config.serviceUrl)) 
      .catch(error => Observable.throw(error.json().error || 'Server error')) 
      .subscribe(t => this._data = t.json()); 
    } 
}