我对可观察物有疑问。我的情况是,我订阅了此主题,并且希望在可观察到的成功响应中运行一个函数。一旦我的函数(foo)完成(此函数必须完成才能继续逻辑以成功完成响应),我想将.next()方法传递给另一个主题。我的问题是,我不知道该如何等待我的函数foo完成并返回值。如果我在另一个主题上对.next()方法调用setTimeout,则一切正常。我只是想避免setTimeout。 我的代码的架构是:
def program(num):
for i in range(num):
print("The number is", i)
runs = 3
for _ in range(runs):
program(5)
如果我在订阅中使用我的代码,如下所示:
this.customService.customSubject$.subscribe((response) => {
this.someValueNeededInFoo = response;
this.foo(); //I need to wait for this function to be executed until I move on
this.customService2.anotherSubject$.next(true); //That will be great if I can wait for this as well
this.customService2.thirdSubject$.next(response); //This should invoke last
});
foo() {
//do some logic stuff
return value;
}
然后一切正常。我想避免使用setTimeout,因为就我而言,它不是真正可靠的。谁能指导我,在这里我该怎么做,以进行一系列这些函数调用? 谢谢!
答案 0 :(得分:0)
您所关注的不是观察性问题,而是this.foo()
是一种异步方法,这意味着它返回了诺言。
您只需在调用.then()
之后将逻辑放在foo()
块中。这样可以确保在foo完成后执行它:
this.customService.customSubject$.subscribe(response => {
this.someValueNeededInFoo = response;
this.foo().then(valFromFoo => {
this.customService2.anotherSubject$.next(true);
this.customService2.thirdSubject$.next(response);
})
});
您可以选择使用async/await
语法,而不使用.then()
。以下代码与上面的示例等效:
this.customService.customSubject$.subscribe(async response => {
this.someValueNeededInFoo = response;
await this.foo();
this.customService2.anotherSubject$.next(true);
this.customService2.thirdSubject$.next(response);
})
});
我想提到,通常不需要创建一堆主题以从其他流中发出值。通常,您可以相互定义流。
代替做这样的事情:
docIdSubject$ = new Subject<string>();
documentSubject$ = new Subject<Document>();
this.someService.id$.subscribe(
id => this.docIdSubject$.next(id)
);
this.docIdSubject$.subcribe(
docId => {
this.docService.getDocument(docId).subscribe(
document => this.documentSubject$.next(document)
);
);
);
您可以从根本不需要对象的可观察源定义可观察对象。
docId$ = this.someService.id$;
document$ = this.docId$.pipe(
switchMap(id => docService.getDocument(id))
);
您可以根据需要使用管道运算符来转换流。请注意,没有内部订阅。我发现将所有数据转换逻辑以声明方式放入流定义(在.pipe()
内)要干净得多,而在实际订阅中只需要做很少的工作。
现在注意,您可以执行document$.subscribe()
。