如何在 Observable 就绪后调用函数

How to call function after observable is ready

我是 Angular 和 Observables 的新手。我的问题是: 在我的组件主页中,我将调用 http.get 和 return 的服务称为可观察的。在我的模板主页上,我对此数据使用异步 $。我需要在 ngOnInit 中调用另一个 void 函数,它将在 returned 时使用 data$。所以我不知道该怎么做。

HomePage.ts

export class HomePage implements OnInit {

  data$: Observable<any>;

  ngOnInit(): void {
    //I need userId that will be returned here
    this.data$ = this.dataService.getMyData(); 
    //how to call this function after data$ is returned?
    this.sendMessage(data.userId);
  }

  sendMessage(data.userId){
     //send this userId 
  }
}

HomePage.html

<app-homepage form="true" *ngIf="{ data: data$ | async} as myData">
<div *ngIf="data.userId">
///....

我试过这个:但每次我在页面上输入一些数据时 - 它会多次调用 sendMessage()...

this.data$ = this.dataService.getMyData().pipe(
      tap((data) => {
        this.sendMessage(data.userId);
        console.log("in pipe")//here I see multiple calls when I click on checkbox for exemple..
      }));

使用 tap 运算符是在通过流发出值时 运行 副作用的适当方法。

如果你想防止多个订阅触发副作用逻辑,你可以使用shareReplay运算符来防止这种行为:

this.data$ = this.dataService.getMyData().pipe(
    tap(data => this.sendMessage(data.userId)),
    shareReplay()
);

这是一个 StackBlitz 样本

each time I input some data on the page - it calls sendMessage() multiple times

如果与页面交互导致多次执行调用,则更改检测可能以某种方式导致此问题。您可能需要共享更多代码才能弄清楚为什么会这样。

如果您的服务返回 Observable,那么您需要 subscribe 才能读取响应内容,如下所示:

export class HomePage implements OnInit {

  // data$: Observable<any>;
  theResult: any;

  ngOnInit(): void {    
    this.dataService.getMyData().subscribe((response) => {
      console.log('See your response', response);
      theResult = response.userId;
      this.sendMessage(theResult);
    });
  }

  sendMessage(data.userId){
     //send this userId 
  }
}

请记住,当你 subscribe 到一个 Observable 时,那是一个 asynchronous 操作,这就是为什么,在你得到 response 之后 subscribe 步骤,您将需要调用您的其他函数。

尝试

this.data$ = this.dataService.getMyData().pipe(
  take(1),
  tap((data) => {
    this.sendMessage(data.userId);
    console.log("in pipe")//here I see multiple calls when I click on checkbox for exemple..  
  }
));