Angular rxjs 混合 observable 和 promises
Angular rxjs mix observable and promises
我正在开发一个 Angular 应用程序,我使用 Rxjs、Observables 和所有东西将数据从我的数据访问层传输到组件。
我有一个服务可以获取 Bootstrapping 数据(名为 B)。
另一个服务(名为 A)获取这些数据并通过 Subject 将它们提供给组件。
我的目标是将这些数据保留在我的服务 A 中,但仅限于我第一次获取数据时。所以,我将使用 Promise。
我需要对主题 "subscribe" 的承诺,然后直接 "unsubscribe"。
我尝试了 BehaviorSubject、ReplaySubject,但 Promise 从未被调用...
Bootstrap 服务
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
获取数据并将其传输到组件的服务
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
模块和Bootstrapping 配置
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}
我建议继续使用 Observables。管道运算符 share 将 Observable 的结果共享给订阅此 Observable 的每个人。只调用一次。
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}
我正在开发一个 Angular 应用程序,我使用 Rxjs、Observables 和所有东西将数据从我的数据访问层传输到组件。
我有一个服务可以获取 Bootstrapping 数据(名为 B)。 另一个服务(名为 A)获取这些数据并通过 Subject 将它们提供给组件。
我的目标是将这些数据保留在我的服务 A 中,但仅限于我第一次获取数据时。所以,我将使用 Promise。
我需要对主题 "subscribe" 的承诺,然后直接 "unsubscribe"。
我尝试了 BehaviorSubject、ReplaySubject,但 Promise 从未被调用...
Bootstrap 服务
export class BService {
propsFetched: Subject<BootstrapProperties> = new Subject<BootstrapProperties>();
constructor(private httpClient: HttpClient) { //... }
init() {
this.fetchBootstrapProperties().then(
(res) => {
// ...
this.propsFetched.next({ ...res });
}
);
}
private fetchBootstrapProperties(): Promise<BootstrapProperties> {
const url = UrlResolver.resolveUrl(UrlResolver.EndPoint.BOOTSTRAP);
return this.httpClient.get<BootstrapProperties>(url).toPromise();
}
getDefaultData(): Observable<Data> {
return this.propsFetched.pipe(map(data => {
// Some data computation
return data;
}));
}
}
获取数据并将其传输到组件的服务
export class AService {
sub$ = new BehaviorSubject<Data>();
constructor(private bService: BService) {
// This one works, it's used by my component.
this.sub$ = this.bService.getDefaultData() as BehaviorSubject<Data>;
// Now, I want to "keep a copy" of these data, ... But my promise never fires.
this.sub$.toPromise().then(d => console.log(d));
}
模块和Bootstrapping 配置
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule,
// ...
],
providers: [
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [BService],
multi: true
}
],
bootstrap: [AppComponent]
})
export class AppModule { }
export function init(bService: BService) {
return () => bService.init();
}
我建议继续使用 Observables。管道运算符 share 将 Observable 的结果共享给订阅此 Observable 的每个人。只调用一次。
export class BService {
public fetchBootstrapProperties$: Observable<BootstrapProperties>;
constructor() {
this.fetchBootstrapProperties$ = this.httpClient.get<BootstrapProperties>(url).pipe(
map(data => {
// computation
// return data
}),
share()
);
}
}
export class AService {
constructor(bService: BService) {
this.bService.fetchBootstrapProperties$.subscribe(data => {
// get your data
);
}
}