2016-11-17 1 views
1

여기 거래가 있습니다. JSON 목록 개체를 반환하는 HTTP get 요청이 있습니다. RxJS를 사용하여 해당 목록의 데이터를 수신합니다. 이제 해당 목록에있는 각 객체에 대해 다른 HTTP 요청을 수행 한 다음 해당 요청의 결과를 배열에 저장하려고합니다.RxJS 관측치를 순차적으로 사용하는 방법은 무엇입니까?

지금까지이 작업을 수행 할 수 있었지만 데이터로 초기 목록의 순서를 유지하는 방법을 파악할 수 없습니다. 이것은 아마도 Observable 메커니즘 전체가 비동기 적이라는 사실과 관련이 있습니다.

ngOnInit(): void { 
    this.shiftInformationService.getShifts("2016-11-03T06:00:00Z", "2016-11-06T06:00:00Z") 
     .subscribe(shifts => { 
      shifts.forEach(shift => { 
       this.addDataToAreaChart(shift.startDateTime, shift.endDateTime, shift.description); 
      }); 
     }); 

} 

addDataToAreaChart(startDate: string, endDate: string, description: string) { 
    this.machineStatisticsService 
     .getCumulativeMachineStateDurations(startDate, endDate) 
     .subscribe(s => { 
      this.areaChartData = []; 
      this.areaChartData.push(new AreaChartData(startDate, endDate, description, s)); 
     }); 
} 

내가 원하는 것은 areaChartData 배열의 데이터를 밀어 때 shifts.forEach 루프에서 호출의 순서를 유지하는 것입니다 :

여기 내 코드입니다.

아이디어가 있으십니까? 도와 주시면 감사하겠습니다!

업데이트 : 해결!

최종 코드 : 마이클

ngOnInit(): void { 
    var startDate = new Date(); 
    startDate.setDate(startDate.getDate() - 3); 

    this.shiftInformationService.getShifts(DateUtil.formatDate(startDate), DateUtil.formatDate(new Date())) 
     .subscribe(shifts => { 
      Observable.from(shifts) 
       .concatMap((shift) => { 
        return this.machineStatisticsService 
         .getCumulativeMachineStateDurations(shift.startDateTime, shift.endDateTime) 
         .map((result) => { 
          return { 
           "addDataToAreaChartValue": result, 
           "shift": shift 
          } 
         }); 
       }) 
       .subscribe(s => { 
        this.areaChartData = []; 
        this.areaChartData.push(
         new AreaChartData(
          s.shift.startDateTime, 
          s.shift.endDateTime, 
          s.shift.description + ' ' + s.shift.startDateTime.slice(5, 10), 
          s.addDataToAreaChartValue 
         ) 
        ); 
       }); 
     }); 
} 

감사합니다!

+0

가 수행 할 필요가있다. – KwintenP

+0

다른 하나는 충분합니다 :) – thebobblob

답변

4

concatMap을 사용하면 순서대로 처리 할 수 ​​있습니다.

각 소스 값을 Observable 출력에 병합 된 Observable에 투영합니다. 직렬화 된 방식으로 각 소스 값을 병합하기 전에 대기합니다.

map을 사용하면 관찰 가능 값을 추가/변환 할 수 있습니다.

소스가 Observable에서 방출 한 각 값에 지정된 프로젝트 함수를 적용하고 결과 값을 Observable로 내 보냅니다.

그래서, 당신은 요청을 병렬로 수행 될 필요하거나 하나씩 수행 할 수있는이

ngOnInit(): void { 
    this.shiftInformationService.getShifts("2016-11-03T06:00:00Z", "2016-11-06T06:00:00Z") 
     .subscribe(shifts => { 
      Rx.Observable.from(shifts) // create observable of each value in array 
       .concatMap((shift) => { // process in sequence 
        return this.addDataToAreaChart(
         shift.startDateTime, 
         shift.endDateTime, 
         shift.description 
        ).map((result) => { 
         return { 
          "addDataToAreaChartValue" : result, // addDataToAreaChart result 
          "shift": shift // append shift object here, so we can access it on subscribe 
         } 
        }); 
       }) 
       .subscribe(s => { 
        //this.areaChartData = []; // why?? 
        this.areaChartData.push(
         new AreaChartData(
          s.shift.startDate, 
          s.shift.endDate, 
          s.shift.description, 
          s.addDataToAreaChartValue 
         ) 
        ); 
       }); 
     }); 
} 

addDataToAreaChart(startDate: string, endDate: string, description: string) { 
    return this.machineStatisticsService 
     getCumulativeMachineStateDurations(startDate, endDate); 
} 
+0

고마워요, 이것으로 훨씬 더 명확 해집니다. 그러나 :이 부분에'shift'에서 데이터를 필요'this.areaChartData.push ( 새로운 AreaChartData ( 의 startDate, endDate가, 설명, 의 를) ) 내가 어떻게 할 것'? – thebobblob

+0

@thebobblob'map'을 사용하여'shift' 객체를 추가 할 수 있습니다. 나는 대답을 편집했습니다. 저에게 알려주세요. – Michael

관련 문제