TypeScript - 等待 observable/promise 完成,并返回 observable
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37304160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript - wait for an observable/promise to finish, and return observable
提问by Geoffrey D
I am quite new to TypeScript & RxJS, and I am trying to return an Observable
after another Observable
is finished:
我对 TypeScript 和 RxJS 很陌生,我试图在一个Observable
又一个Observable
完成后返回:
public myObservable = () : Observable<boolean> => {
console.log('retrieving the token in DB');
return Observable.create(observer => {
setTimeout(() => {
observer.next(true);
observer.complete();
}, 5000);
});
}
public makeRequest = (): Observable<any> => {
return this.myObservable().subscribe(
function (x) {
console.log('I have the token, now I can make the HTTP call');
return this.http.get('http://jsonplaceholder.typicode.com/posts/1')
.map( (responseData) => {
return responseData.json();
})
.map((item:any) => {
return {
id: item.id,
userId: item.userId,
title: item.title,
body: item.body
};
});
},
function (err) {
console.error('Error: ' + err);
},
function () {
console.log('Completed');
});
}
I received this error: "Returned expression type subscription is not assignable to type Observable<any>
".
我收到此错误:“返回的表达式类型订阅不可分配给类型Observable<any>
”。
I totally understand the error here (an Observable is like a stream, and a subscription is the fact of "observing" that stream), but I don't see how to "wait" for an Observable
(or a promise)to finish to return a new Observable
. How can I do that?
我完全理解这里的错误(Observable 就像一个流,订阅是“观察”该流的事实),但我不知道如何“等待” Observable
(或承诺)完成返回一个新的Observable
。我怎样才能做到这一点?
采纳答案by Radim K?hler
The problem is that we convert observable into different type... with .subscribe
- while we should not (it does not return observable)
问题是我们将 observable 转换为不同的类型.......subscribe
而我们不应该(它不返回 observable)
public makeRequest = (): Observable<any> => {
return this.myObservable().subscribe(
... // this is wrong, we cannot return .subscribe
// because it consumes observable and returns ISusbcriber
);
}
When we have an observable... we should just take its result and use .map to convert it to something else
当我们有一个 observable 时……我们应该只获取它的结果并使用 .map 将其转换为其他内容
FlatMap
operatortransform the items emitted by an Observable into Observables, then flatten the emissions from those into a single Observable
FlatMap
操作员将 Observable 发出的项目转换为 Observable,然后将这些项目的排放扁平化为单个 Observable
public makeRequest = (): Observable<any> => {
return this.myObservable()
.flatmap((x) => return this.http
.get('http://jsonplaceholder.typicode.com/posts/1')
.map( (responseData) => {
return responseData.json();
})
...
Check all the details here
在此处查看所有详细信息
TAKING ADVANTAGE OF OBSERVABLES IN ANGULAR 2
利用 Angular 2 中的 observables
回答by rbj325
While flatMap() may work, since you are not passing in a parameter that is used[see param (x)], the best operator for you to use in this scenario is forkJoin().
虽然 flatMap() 可能会起作用,但由于您没有传入使用的参数[参见 param (x)],因此在这种情况下最适合您使用的运算符是 forkJoin()。
Please see this example: https://stackoverflow.com/a/38049268/1742393
请看这个例子:https: //stackoverflow.com/a/38049268/1742393
Observable.forkJoin(
this.http.get('/app/books.json').map((res:Response) => res.json()),
this.http.get('/app/movies.json').map((res:Response) => res.json())
).subscribe(
data => {
this.books = data[0]
this.movies = data[1]
},
err => console.error(err)
);
回答by Geraldo Sérgio Sim?o
I am looking for this answer some days because this is my problem too. Today I have the answer and would like to share.
几天我正在寻找这个答案,因为这也是我的问题。今天我有了答案,想分享一下。
The code is:
代码是:
ngOnInit() {
var idEntidade: number;
this.route.paramMap.subscribe(params => {
idEntidade = Number(params.get('id'));
});
this.dataService.getEstados().subscribe(data => {
this.estados = data;
});
var dados = this.dataService.getCliente(idEntidade);
**this.subscription = dados.subscribe(
(data: Cliente) => { this.entityForm.patchValue(data);},
null,
() => { this.completed(); }
);**
}
and the function completed will be executed after the subscribe is complete.
订阅完成后执行完成的函数。
completed(){
let idEstado: number = this.entityForm.controls['estadoId'].value;
if (idEstado === null) {
return;
}
this.dataService.getMunicipiosByEstado(this.entityForm.controls['estadoId'].value)
.subscribe(data => { this.municipios = data; });
}
Hope this helps.
希望这可以帮助。