angular 2+ Promises,Observable和async pipe

时间:2017-09-28 17:56:18

标签: angular angular-promise angular2-observables

我正在以角度4进行我的第一个项目并遇到了一个小问题。

当我打电话给服务器时,有一个延迟,我已经学会使用异步管道来显示我从服务器获取的数据。

但我遇到的问题是,例如,我说服务器发出HTTP调用,现在我正在等待信息从服务器回来。但我需要这些信息来进行一些数字处理。因此,我所分配的等待来自服务器的信息的变量将返回为未定义,因为运行时的代码已执行,并且没有可用于分配它们的值。

ngOnInit(){
    this.settings = this.settingsService.getSettings();
    console.log("Logging Settings: " + this.settings);  // ends up being undefined
  }

onDoSomething(){
    return this.settings * gazillion;  // doesn't work 
}

什么是进行服务调用的正确方法,让方法DoSomething知道要等到你得到设置?此外,如果您在整个应用程序中使用设置,您将如何存储它,这样您每次需要设置时都不会经常进行HTTP调用。

我的直觉是让app.componenet.ts进行调用和存储。

谢谢!

3 个答案:

答案 0 :(得分:0)

通常服务于角度2返回可观察量。 这是因为http请求需要花费不同的时间来返回来自服务器的数据。

我不确定getsettings究竟做了什么,但总体设置如下:

//service layer
    function getSettings() {
        return this.http.get(`server-url`)
            .map((response: Response) => <any>response.json())
            .catch(this.handleError);
}

private handleError(error: Response) {
    return Observable.throw(error.json() || 'Server error');
}
//in your component
this.service.getSettings().subscribe(result => {this.settings = result}, error => {console.log("there was an error.")});

在http请求响应客户端后,订阅部分被触发。

答案 1 :(得分:0)

在此过程中有几件事可以帮助你:

  • 如果数据已准备好直接从服务器提供,则异步管道非常适合。如果你在组件中需要它,请不要使用异步管道而只是订阅。
  • Angular会从http请求中返回一个observable,然后您可以使用subcribe()函数并提供一旦检索到数据或失败就想要发生的操作。

Here is a good tutorial on using http in an angular service

在您的特定情况下,您需要这样的内容:

ngOnInit(){
    this.settings = this.settingsService.getSettings().subscribe((settings)=>{
    this.settings = settings;
    console.log("Logging Settings: " + this.settings);
}

要回答第二个问题,Angular服务,如果按照开发人员的意图完成,请遵循Singleton Pattern,并且是整个应用程序的共享资源。这意味着访问它的所有内容都接收与其他任何内容相同的实例。

答案 2 :(得分:0)

根据您实际想要实现的目标,这是do或map运算符的完美用例:

this.settings = this.settingsService.getSettings().do(settings => this.doSomething(settings));

如果你只是想要一个“副作用”,就像你实际上不想影响你发送显示的数据一样,你只想做一些与显示它无关的其他东西,但你需要它发生在序列中的某个点(我经常使用do()隐藏页面范围内容加载弹出窗口等)。无论doSomething()是否返回值都没关系,因为它不会被使用。

this.settings = this.settingsService.getSettings().map(settings => this.transformSettings(settings));

如果您想要实际更改要发送到显示器的数据,则地图运算符会大量用于此情况。 transformSettings()必须返回一个值,即您要特定显示的值,因为这将传递给最终订阅者。

对于第2部分,将结果存储在服务层的行为主题中,以便它始终可用于需要它的任何组件:

private settingsSource = new BehaviorSubject(null);
settings$ = this.settingsSource.asObservable().filter(e => !!e); //this prevents the initial null value from being sent
loadSettings() {
    this.http.get('settings').map(r => r.json()).subscribe(this.settingsSource);
}
constructor(private http: HttpClient) {
  this.loadSettings();
}

然后让你的组件订阅设置$,只要它到达那里它就会在那里。