TypeScript - 等待 observable/promise 完成,然后返回 observable
Posted
技术标签:
【中文标题】TypeScript - 等待 observable/promise 完成,然后返回 observable【英文标题】:TypeScript - wait for an observable/promise to finish, and return observable 【发布时间】:2016-09-15 05:00:24 【问题描述】:我对 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');
);
我收到此错误:“返回的表达式类型订阅不可分配给类型 Observable<any>
”。
我完全理解这里的错误(Observable 就像一个流,而订阅是“观察”该流的事实),但我不知道如何“等待” Observable
(或承诺) 完成以返回新的 Observable
。我该怎么做?
【问题讨论】:
很好的提示!我的 2 美分:flatMap() 似乎在 rxjs 5.0.1 中不可用。我使用 mergeMap() 来实现可观察对象的“链”,或者换句话说 - 有一个外部和 2 个内部可观察对象。 【参考方案1】:有些日子我正在寻找这个答案,因为这也是我的问题。今天我有了答案,想分享一下。
代码是:
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();
);**
并且完成的函数会在订阅完成后执行。
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; );
希望这会有所帮助。
【讨论】:
【参考方案2】:虽然 flatMap() 可能会起作用,但由于您没有传入使用的参数 [参见 param (x)],因此在这种情况下使用的最佳运算符是 forkJoin()。
请看这个例子:https://***.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)
);
【讨论】:
返回的数据顺序是否总是如图所示? this.book = data[0] 和 this.movies = data[1] 是的,它与传递给方法的可观察对象的顺序直接相关。【参考方案3】:问题是我们将 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
);
当我们有一个 observable 时......我们应该只获取它的结果并使用 .map 将其转换为其他东西
FlatMap
operator将 Observable 发出的项目转换为 Observables,然后 将这些排放量扁平化为单个 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();
)
...
在这里查看所有详细信息
TAKING ADVANTAGE OF OBSERVABLES IN ANGULAR 2
【讨论】:
平面图/合并图示例:stackblitz.com/edit/angular-mergemap以上是关于TypeScript - 等待 observable/promise 完成,然后返回 observable的主要内容,如果未能解决你的问题,请参考以下文章
html 使用AJAX POST请求来调用控制器操作(在页面加载时和在下拉列表中选择项目时),获取返回的布尔值,设置observabl