角度-多个订阅序列不起作用

时间:2019-07-26 07:28:49

标签: angular rxjs

在角度我想创建多个订阅序列。当第一个订阅完成时,请进行下一个订阅。与此类似。

this.globalCtrl.getSon().subscribe(
                  response => {
                    this.son= response;
                  },
                  error => {
                    console.log(error);
                  },
                  () => {
                   //DOESN´T ENTER IN THIS SUBSCRIBE
                    this.dashboardCtrl.getMarkers(this.son).subscribe(

                      response => {
                        this.markers = response["body"]["data"];
                        if (this.markers.length == 0) {
                          this.toast.fire({
                            type: "error",
                            title: "No hay datos geográficos del grupo seleccionado"
                          });
                        }
                        this.timezone = response["body"]["timezone"];
                      },
                      error => {
                        console.log(error);
                      }
                    );

问题:没有输入第二个订阅,并且“响应”中有数据。 ¿有人知道我该怎么做吗?

更新

如果我将第二个订阅放在这样的响应中

  this.globalCtrl.getSon().subscribe(
                      response => {
                        this.son= response;
                        this.dashboardCtrl.getMarkers(this.son).subscribe(

                          response => {
                            this.markers = response["body"]["data"];
                            if (this.markers.length == 0) {
                              this.toast.fire({
                                type: "error",
                                title: "No hay datos geográficos del grupo seleccionado"
                              });
                            }
                            this.timezone = response["body"]["timezone"];
                          },
                          error => {
                            console.log(error);
                          }
                        );

有效,但是视图不显示数据。当我刷新视图数据时,将正确加载数据,但在第一次加载时不会加载数据。

更新2:使用开关映射

  this.globalCtrl.getfather().pipe(
      switchMap(son=> this.dashboardCtrl.getMarkers(son.toString()).subscribe( /ERROR
        response => {
          this.markers = response["body"]["data"];
          if (this.markers.length == 0) {
            this.toast.fire({
              type: "error",
              title: "No hay datos geográficos del grupo seleccionado"
            });
          }
          this.timezone = response["body"]["timezone"];
        },
        error => {
          console.log(error);
        }
      )
    );
  

OperatorFunction中不存在属性订阅

也许可以观察到导致错误

 getFather(): Observable<any> {
    return this.grupo.asObservable();
  }

4 个答案:

答案 0 :(得分:2)

建议您将一个订阅嵌套在另一个订阅中。这使得管理变得困难,并且几乎无法正确取消订阅。而是使用switchMap

这是我的一个示例应用程序中的一个示例:

  todosForUser$ = this.http.get<User>(`${this.userUrl}/${this.userName}`)
    .pipe(
      switchMap(user =>
        this.http.get<ToDo[]>(`${this.todoUrl}?userId=${user.id}`)
      )
    );

您可以在此处查看此代码:

https://stackblitz.com/edit/angular-todos-deborahk

使用您的代码,就像这样(不检查语法):

import { switchMap } from 'rxjs/operators';

this.globalCtrl.getSon()
 .pipe(
    switchMap(son => this.dashboardCtrl.getMarkers(son))
 ).subscribe(...);

更新:简化的初始示例,最初演示了如何处理与多个相关的数据集。

答案 1 :(得分:1)

您的第二个订阅放置在错误的位置。它应该在第一次订阅的响应之内

this.globalCtrl.getSon().subscribe(
                  response => {
                    this.son= response;
                    // ADD THE OTHER SUBSCRIBE HERE
                  },
                  error => {
                    console.log(error);
                  }

可观察的回调具有3种类型-nexterrorcomplete

您将第二个订阅放入complete回调中,这就是从未调用它的原因(您的第一个可观察到的对象从未完成)。

详细了解可观察对象here

答案 2 :(得分:1)

您必须将第二个订阅移到第一个订阅中:

this.globalCtrl.getSon().subscribe(
              response => {
                this.son= response;
                  this.dashboardCtrl.getMarkers(this.son).subscribe(
                  response => {
                    this.markers = response["body"]["data"];
                    if (this.markers.length == 0) {
                      this.toast.fire({
                        type: "error",
                        title: "No hay datos geográficos del grupo seleccionado"
                      });
                    }
                    this.timezone = response["body"]["timezone"];
                  },
                  error => {
                    console.log(error);
                  }
              },
              error => {
                console.log(error);
              } 
                );

答案 3 :(得分:0)

在订阅中包含订阅称为平移

使用switchMap作为对@DeborahK的回答,这是可行的,但这是对它的滥用。如果已经订阅了第一个可观察对象,则switchMap将是一个可行的方法。更好的方法是使用mergeMap(先前称为flatMap

mergeMap -当您有一个Observable的结果是另一个Observable时使用

switchMap -当您具有可更改的Observable且其结果是另一个Observable时使用

如果您的第一个Observable发出某些内容,则mergeMap不会丢弃前一个Observable,因此您的内部订阅仍将订阅前一个Observable。在switchMap中,它将丢弃先前的Observable,而内部订阅将订阅内部订阅。

解决方案:

import { mergeMap } from 'rxjs/internal/operators/mergeMap';
.......
.......

this.globalCtrl.getSon().pipe(
  mergeMap((response) => {
    this.son = response;
    return this.dashboardCtrl.getMarkers(this.son)
  })
).subscribe((res) => {
  this.markers = response["body"]["data"];
});