如何"链" Angular 2中的两个单独的可观察量

时间:2016-08-10 10:03:09

标签: angular typescript observable

我正在使用Angular2开发一个Web应用程序,我从服务器获取数据时遇到了一些问题。

 import ...

 @Component({
 ...

 })
 export class EmployeeManagementTableComponent implements OnInit, OnDestroy{

private employees: Employee[];
private departments: SelectItem[] = [];
private selectedDepartment: string;
private columns: any[];
private paramSub: any;
private employeesSub: any;
private departmentSub: any;


constructor(private employeeManagementService: EmployeeManagementService, 
            private route: ActivatedRoute, 
            private router: Router,
            private ccs: ComponentCommunicatorService,
            private logger: Logger) { }

ngOnInit(){

    this.columns = [
     ...
    ];

    //ccs is just a service for storing/getting app wide infomation

    this.selectedDepartment = this.ccs.getSelectedDepartment();
    this.getDepartments();
    this.getEmployees(this.selectedDepartment);

    ...
}

ngOnDestroy(){
    /*this.employeesSub.unsubscribe();
    this.departmentDub.unsubscribe();*/
}

getDepartments(){

    this.departments.push({label: 'Alle', value: 'all'});

    this.departmentSub = this.employeeManagementService.getDepartments().subscribe(
          data =>  {data.forEach((item, index) => {
                        this.departments.push({label: item, value: index.toString()});
                    });    
                   },
          err => this.logger.error(err),
          () => {this.logger.log('done loading');
                 this.departmentSub.unsubscribe()}
    );
}
getEmployees(department: any){

this.employeesSub = this.employeeManagementService.getEmployees(department).subscribe(
          data => {this.employees = data},
          err => this.logger.error(err),
          () => {this.logger.log('done loading');
                 this.employeesSub.unsubscribe()}
    );
}

当您看到组件被初始化时,它会调用两个获取数据的方法。这些方法从我的服务中获得可观察性并订阅它们 问题是订单就像call1, call2, result1, result2, ...,我认为有些事情是不对的。它应该是call1, result1, call2, result2, ...还是我错了?我尝试在observable1的onComplete中订阅observable2,但我认为专用方法将毫无用处。 我已经研究并找到了一些解决方案,同时使用concat同时订阅了两个observable,但我只是希望代码在所有数据流量完成后继续在getDepartments()之后继续。

我是否应该取消订阅OnDestroy()OnComplete subscribe功能,我真的无法与众不同?

2 个答案:

答案 0 :(得分:12)

如果要控制observable的执行顺序,则需要构建一个利用flatMap(串行执行)或Observable.forkJoin(并行执行)等运算符的异步数据流

以下是样本:

// Series
someObservable.flatMap(result1 => {
  return someOtherObservable;
}).subscribe(result2 => {
  (...)
  (...)
});

// Parallel
Observable.forkJoin([ someObservable, someOtherObservable ])
  .subscribe(results => {
    let result1 = results[0];
    let result2 = results[1];
  });

答案 1 :(得分:0)

通常,这种调用是异步的,因此,执行顺序和/或到达结果不是确定性的。 (例如:当从API 1请求数据,然后从API 2请求数据时,如果API 1特别慢或数据量很大,它甚至可能导致API 2中的数据到达来自API 1的数据之前。)所以,回答你的问题第一个问题:是的,你错了。

订阅Observable时,您可能会有一些回调函数(使用或存储接收数据的位置),一旦数据到达,它将由第一个服务执行。如果仅在收到第一次调用的结果后触发第二个API调用很重要,则此函数将是从第二个服务请求数据的位置。 当然,您不希望将服务1和服务2耦合在一起,因此更好的方法是将回调函数传递给服务1,以便在成功时调用。然后,您的客户端代码可以确保此回调函数从第二个服务请求数据。当然,有很多方法可以处理这种情况,我之前描述的只是一种简单的方法。

关于取消订阅问题:通常,在接收结果时不希望取消订阅,因为之后可能会有更多数据进入。 (这是Promises和Obvservables之间的主要区别之一)。例如,在我正在处理的应用程序中,我在“离开”组件时取消订阅,因为我希望在收到初始数据后继续订阅。