如何强制我的函数按顺序调用?

时间:2019-02-23 20:56:03

标签: angular typescript observable behaviorsubject

摘要:我有一个图表组件,一个过滤器菜单组件以及一个用于过滤和设置BehaviorSubject的服务。我希望我的服务最初进行http调用以获取数据,我的过滤器菜单将过滤器日期传递给该服务以过滤数据,最后希望我的图表组件订阅BehaviorBehavior,以便它可以显示过滤的数据。

过滤器菜单组件:

export class FilterMenuComponent {
startDate: string;
endDate: stirng;

constructor(private service: FilterService) { }

ngOnInit() {
    this.service.setData();
    this.setDates();
}

setDates() {
    //grabs dates from ui
    this.service.filterData(startDate, endDate);
}

过滤服务:

export class FilterService {
filteredDataBS: BehaviorSubject<Data>;
data: Data;

constructor(private _http: HttpClient) { }

setData() {
    //http call to get initial data
    this._http.get().subscribe(data => {
        this.data = data;    
    });
}

filterData(startDate: string, endDate: string) {
    this.data = this.data.filter(xxxxxxxxxxxxxx); 
    this.filteredDataBS.next(data);
}

图表组件:

export class ChartComponent {
data: Data;

constructor(private service: FilterService) { }

ngOnInit() {
    this.service.filteredDataBS.subscribe(data => {
        this.data = data;
    });
}

问题:由于设置初始数据的http调用可能需要花费相当长的时间,因此FilterMenuComponent已经开始进行并调用了过滤数据。然后,我在调用.filter on undefined时遇到错误。我需要FilterMenuComponent等待并调用this.service.filterData(),直到 FilterService 之后从http调用获取了其初始数据。

4 个答案:

答案 0 :(得分:0)

您必须从函数setData返回一个observable,以检测何时过滤数据。这是您的操作方法:

setData() {
  // Return an Observable to detect when data has
  // been received
  return new Obervable(observer => {
    //http call to get initial data
    this._http.get().subscribe(data => {
      this.data = data;
      observer.next();
    });
  });
}

然后在您的FilterMenuComponent中订阅了可观察对象:

ngOnInit() {
  this.service.setData().subscribe(() => {
    this.setDates();
  });
}

答案 1 :(得分:0)

以下是解决方案

过滤器菜单组件:

export class FilterMenuComponent {
startDate: string;
endDate: stirng;

constructor(private service: FilterService) { }

ngOnInit() {
    this.service.setData();
    this.filteredDataBS.subscribe(result =>  this.setDates());
}

setDates() {
    //grabs dates from ui
    this.service.filterData(startDate, endDate);
}

过滤服务:

export class FilterService {
filteredDataBS: BehaviorSubject<Data>;
data: Data;

constructor(private _http: HttpClient) { }

setData() {
    //http call to get initial data
    this._http.get().subscribe(data => {
        this.data = data;    
        this.filteredDataBS.next(data);
    });
}

filterData(startDate: string, endDate: string) {
    this.data = this.data.filter(xxxxxxxxxxxxxx); 
    this.filteredDataBS.next(data);
}

使用filteredDataBS指示何时加载日期数据,然后通过订阅使用它

答案 2 :(得分:0)

以下是解决方案

过滤器菜单组件:

ngOnInit() {
    this.service.setData();
    this.filteredDataBS.subscribe(result =>  this.setDates());
}

过滤服务:

setData() {
    //http call to get initial data
    this._http.get().subscribe(data => {
        this.data = data;    
        this.filteredDataBS.next(data);
    });
}

使用filteredDataBS指示何时加载日期数据,然后通过订阅使用它

答案 3 :(得分:0)

代替在setDates()的{​​{1}}中调用ngOnInit,可以在FilterMenuComponent回调中调用它:

_http.get()

,但需要传递setData(startDate, endDate) { //http call to get initial data this._http.get().subscribe(data => { this.data = data; this.filterData(startDate, endDate); }); } startDate。您还可以将此变量作为属性保存在FilterService类中。

如果您不这样做,只需像其他用户建议的那样从endDate返回有限的Observable。