[英]How do I make sure one Subcription finishes before another?
globleVariable: any;
ngOnInit() {
// This doesn't work. methodTwo throws error saying "cannot read someField from null. "
this.methodOne();
this.methodTwo();
}
methodOne() {
this.firstService.subscribe((res) => { this.globleVariable = res });
}
methodTwo() {
this.secondService.subscribe((res) => { console.log(this.globleVariable.someField) });
}
如上所示, methodOne
设置了methodTwo
globleVariable
它,因此前者必须先于后者运行完毕。
我想知道如何实现这一目标。
不要订阅方法,而是将它们组合成一个 stream 并在ngInit()中订阅它。 您可以使用tap来执行您之前在subscribe()中执行的更新globaleVariable的副作用。
在下面的示例中,“方法”被转换为字段,因为它们不再是方法(如果需要,您可以将它们保留为方法)。 然后使用concat运算符创建单个 stream,其中 methodOne $将执行,然后当它完成时, methodTwo$将执行。
因为concat按顺序执行,所以可以保证globaleVariable将在methodTwo$开始之前由 methodOne $设置。
globleVariable: any;
methodOne$ = this.someService.pipe(tap((res) => this.globleVariable = res));
methodTwo$ = this.someService.pipe(tap((res) => console.log(this.globleVariable.someField));
ngOnInit() {
concat(this.methodOne$, this.methodTwo$).subscribe();
}
您可以创建一个主题,observable 2 将等待订阅,如下所示:-
globalVariable: any;
subject: Subject = new Subject();
methodOne() {
this.someService.subscribe((res) => { this.globleVariable = res; this.subject.next(); });
}
methodTwo() {
this.subject.pipe(take(1), mergeMap(() => this.someService)).subscribe((res) => {
console.log(this.globleVariable.someField) });
}
在订阅产生后保证方法调用的唯一方法是使用订阅回调。
订阅有两个主要回调成功和失败。
所以在订阅 yields 之后实现方法调用的方法是像这样链接它:
globleVariable: any;
ngOnInit() {
this.methodOne();
}
methodOne() {
this.someService.subscribe((res) => {
this.globleVariable = res
this.methodTwo(); // <-- here, in the callback
});
}
methodTwo() {
this.someService.subscribe((res) => { console.log(this.globleVariable.someField) });
}
您可能希望将调用与其他一些rxjs 操作员链接起来以获得更标准的用法。
ngOnInit() {
this.someService.method1.pipe(
take(1),
tap(res1 => this.globleVariable = res1)
switchmap(res1 => this.someService.method2), // <-- when first service call yelds success
catchError(err => { // <-- failure callback
console.log(err);
return throwError(err)
}),
).subscribe(res2 => { // <-- when second service call yelds success
console.log(this.globleVariable.someField) });
});
}
请记住在组件销毁时完成任何订阅,以避免常见的memory 泄漏。
我的看法,
所以当你使用相同的服务但会抛出不同的结果时会有点混乱,所以我在这里使用firstService
和secondService
而不是someService
。
this.firstService.pipe(
switchMap(globalVariable) =>
this.secondService.pipe(
map(fields => Object.assign({}, globalVariable, { someField: fields }))
)
)
).subscribe(result => {
this.globalVariable = result;
})
我喜欢这种方法的一点是,您可以灵活地使用最终结果,因为它与 class 中的任何属性都解耦了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.