我正在使用Angular 8编写应用程序。我对AngularJS的框架感到很陌生。我在Promises方面有很多经验。
我有对后端API的HTTP请求。这些只是GET&POST调用,因为我们的Delphi后端没有任何WebSocket。我已经成功调出了后端API并使用了promises。
我的代码调用后端API以获取要显示给用户的字符串值。
我想知道如何重构代码以使用Observables,这样做是否有好处?
服务
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ILicenseInfo } from './ilicense-info';
@Injectable({
providedIn: 'root'
})
export class AboutService {
constructor(private http: HttpClient) { }
public getVersionNumber() {
const endpoint: string = 'myEndpoint';
const params = {
password: 'yes'
};
return this.http.post<ILicenseInfo>(endpoint, params)
.toPromise()
.then((response: ILicenseInfo) => {
return response.versionNumberField;
});
}
}
组件
import { Component, OnInit } from '@angular/core';
import { Constants } from '../../../../app/core/constants/constants.service';
import { AboutService } from './about.service';
@Component({
selector: 'ns-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent implements OnInit {
public version: string;
constructor(private aboutService: AboutService) { }
public ngOnInit(): void {
this.aboutService.getVersionNumber().then((response: string) => {
this.version = response;
});
}
}
模板
<FlexboxLayout>
<FlexboxLayout>
<Label text="Version:"></Label>
<Label text="{{version}}"></Label>
</FlexboxLayout>
</FlexboxLayout>
RxJS提供了许多operators和方法来修改和控制可观察到的来自源的数据流。更详细的列表here。
例如
合并两个请求
forkJoin([this.http.get('url'), this.http.post('url', '')]).subscribe
resposne => {
// resonse[0] - GET request response
// resonse[1] - POST request response
},
error => {
}
);
将来自一个呼叫的响应作为对另一个请求的输入
this.http.get('url').pipe(
switchMap(getResponse => {
return this.http.post('url', getResponse)
}
).subscribe(
response => { },
error => { }
);
这些是一些最普通的优点。当需要处理多个相互依赖的可观察对象时,RxJS会更有用。
在您的情况下,您可以通过管道传递map
运算符以从响应中返回versionNumberField
属性。
return this.http.post<ILicenseInfo>(endpoint, params).pipe(
map(response: ILicenseInfo => response.versionNumberField)
);
然后您可以订阅该组件以检索发出的值
public ngOnInit(): void {
this.aboutService.getVersionNumber().subscribe(
(response: string) => {
this.version = response;
}
);
}
通过可观察的数据,存在来自非封闭订阅的潜在内存泄漏的风险。 Angular HTTP客户端具有内置的取消订阅机制,但这也会失败。因此,最好在组件中关闭订阅(通常在ngOnDestroy()
挂钩中)。
import { Subscription } from 'rxjs';
httpSubscription: Subscription;
public ngOnInit(): void {
this.httpSubscription = this.aboutService.getVersionNumber().subscribe(
(response: string) => {
this.version = response;
}
);
}
ngOnDestroy() {
if (this.httpSubscription) {
this.httpSubscription.unsubscribe();
}
}