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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 07:08:28  来源:igfitidea点击:

TypeScript - wait for an observable/promise to finish, and return observable

typescriptrxjsobservable

提问by Geoffrey D

I am quite new to TypeScript & RxJS, and I am trying to return an Observableafter another Observableis 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 将其转换为其他内容

FlatMapoperator

transform 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.

希望这可以帮助。