2017-12-09 15 views
1

목표는 ID 컬렉션을 반복하여 각 ID에 대해 HTTP 호출을 만드는 것입니다. 각 ID에 대해 Observable을 반환하는 get() 메서드가있는 서비스를 사용하고 있습니다. get() 메서드가 호출 될 때마다 반환 Observable을 구독하고 배열에 결과를 푸시하려고 시도합니다. 그러면 결국 새 작업에 대해 다른 메서드로 전달됩니다.각도 2/4 & RxJS - forEach 내의 구독 - 모든 관찰 대상 객체가 완료 될 때까지 흐름 제어가 계속되지 않음을 보장합니다.

관련 서비스 방법 :

public get(departmentId: number): Observable<IDepartmentModel> { 
    return super.get<IDepartmentModel>(departmentId); 
} 

참고 : 슈퍼 클래스가 잘 테스트 제대로 작동하는 확인 각도의 HTTP를 활용한다. 참고 departmentService.get() foreach 문 내에서 여러 번 호출되는 사용자들은 전화 : 논리의 문제는 ... 여기

관련 구성 요소 방법이 아니다.

setInitialDepartmentsAssignedGridData(): void { 
    this.settingsForDropdownSelectedCompanyId = this.userForm.get('defaultCompany').get('defaultCompanyId').value; 

    let departments: IDepartmentModel[] = []; 

    this.userService.user.getValue() //confirmed: valid user is being pulled back from the userService (logic is fine here..) 
     .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) // getting a valid match here (logic is fine here..) 
     .departmentIds.forEach(deptId => this.departmentService.get(deptId).first().subscribe(dept => { // getting a valid department back here (logic is fine here...) 
      departments.push(dept); // HERE LIES THE PROBLEM 
    })); 

    this.setDepartmentsAssignedRowData(departments); 
} 

setDepartmentsAssignedRowData(departments: IDepartmentModel[]): void { 
    console.log('setDeptAssignedRowData called'); // confirmed: method is getting called... 
    console.log(departments); // confirmed: fully-composed collection of departments logged to the console... 

    departments.forEach(dept => { 
     console.log(dept); 
    }); // Y U NO WORK!? 

    departments.map((department) => { 
     console.log(department); // Y U NO WORK? 
     this.departmentAssignedRowData.push({ 
      departmentId: department.id, 
      departmentName: department.name 
     }); 
    }); 

    this.departmentAssignedGridOptions.api.setRowData(this.departmentAssignedRowData); 
} 

무엇을하는 것은 콘솔에 기록 얻고 있지만, 문제는, 인은 진정으로 "가"아니다, 완전히 구성된 배열을 부서 - 객체입니다 setDepartmentsAssignedRowData으로 전달되는 것은 빈 배열입니다.

부서 배열이 두 번째 방법으로 전달되기 전에 비동기 작업이 완료되지 않았다고 확신합니다. 내가 온라인으로 읽은 것 중 일부는 forkJoin을 사용한다고하지만이 컨텍스트에서 어떻게 보이는지 알 수 없습니다. 나는 또한 concatMap가 작동 할지도 모르지만,이 컨텍스트에서 어떻게 작동하는지 모르겠습니다 ...

이 컨텍스트에서 RxJS를 사용하여 의도 한 완전하게 작동하는지 확인하려면 어떻게해야합니까? 구성된 부서 배열 은 실제로을 전달할 준비가 되었습니까?

귀하가 제공 할 수있는 통찰력에 감사드립니다. 도움이 많이 감사합니다! 당신이 올바른지

답변

1

, 당신은 당신이 병렬로 만들고 싶어 HTTP 요청 관찰 가능한 배열 될 것입니다

let observableArray = this.userService.user.getValue() 
    .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) 
    .departmentIds.map(deptId => this.departmentService.get(deptId)) // map is building out an array of observables 

forkJoin이 필요합니다. 이제이 배열을 forkJoin에 전달할 수 있습니다.

Observable.forkJoin(...observableArray) 

forkJoin 반환은 observableArray의 결과 배열입니다. (HTTP 요청을 모두 완료 한 경우 정도) forkJoin

그래서 아예 코드가 될 것입니다 완료 observableArray에서 관찰 가능한 모든 때까지 순서대로 다음 연산자를 방출하지 않습니다

let observableArray = this.userService.user.getValue() 
    .userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) 
    .departmentIds.map(deptId => this.departmentService.get(deptId)); 

Observable.forkJoin(...observableArray).subscribe(res => { 
    // res = [resId0, resId1, resId2, ..., resIdX]; 
}); 

결과를 다른 연산자에 전달하는 것에 대해 언급했습니다. 해당 연산자가 데이터 배열()을 전달하는 또 다른 http 요청 인 경우 flatMap 연산자를 사용할 수 있습니다.

Observable.forkJoin(...observableArray) 
    .flatMap(res => { 
     return this.otherApi(res); 
    }) 
    .subscribe(res => { 
     // res is the result of the otherApi call 
    }); 

flatMap은 API 요청을 함께 연결합니다. 그래서 아예 무슨 일이 일어나고 있는지 병렬

  • 완료되면, 실행 두 번째 API에서 관찰 가능한의

    1. 실행 배열 인 (otherApi)
  • +0

    신난다,이 시도 줄 것이다; 고맙습니다! 하나의 질문 : fork하지 않습니다 .Join은 하나 이상의 param을 요구합니까? 나는 observableArray와 Observable에 아무것도 전달하지 않을거야 .forkJoin? –

    +0

    @SteveBoniface forkJoin은 또한 결과를 수정하는 함수 인'selector' 매개 변수를 사용합니다. 그러나이 경우 선택적이며 필요하지 않습니다. 그것은 조직적 일입니다. 다음 연산자에서 똑같은 수정을 할 수 있습니다 – LLai

    +1

    아, 물론입니다. 나는이 맥락에서 그것을 필요로하지 않을 것이다. 나는 당신의 제안을 시도했다. (완성 된 솔루션을보기 위해 나의 초기 게시물을 편집 할 것이다. 당신의 통찰력에 대해 충분히 감사 할 수 없다.) 이것은 이제 2 ~ 3 일 동안 지속되는 두통을 저장했다. 명성! 고맙습니다 –