2017-11-11 6 views
0

게시 방법에 문제가 있습니다. 나는 항상 내 temporarySegment에서 빈 segmentdata 객체를 얻는다. 저는 숫자와 같은 방식으로 작업을합니다. subscribe의 변수 결과는 SegmentData이며, console.log에서 예상되는 응답을 수신합니다. 그게 어떻게 가능해? 내 방법 :구독시 데이터를 할당 할 수 없습니다

onGetSegmentsClick(size: number) { 
    debugger; 
    if (size > 0) { 
     let counter = 0; 
     let temporarySegment = new SegmentData(); 
     while (counter < size) { 
      this.segmentService.getSegment(counter + 1, this.elementId, this.documentId).subscribe(result => { 
       console.log("get segment request is sended"); 
       temporarySegment = result; 
       console.log("gotten message is:", result); 
      }); 
      ModalComponent.segmentsCollection.push(new SegmentData()); 
      ModalComponent.segmentsCollection[ModalComponent.segmentsCollection.length - 1] = 
       ModalComponent.newer.TemporaryObjectEqualizer(temporarySegment); 
      ModalComponent.segmentsCollection[ModalComponent.segmentsCollection.length - 1].SegmentDataId = 
       counter + 1; 
      counter++; 
     } 
    } 
} 

내 getSegment 방법 :

getSegment(segmentId: number, elementId: string, documentId: string) { 
    let headers = new Headers(); 
    headers.append("Content-type", "application/json"); 
    let input = { 
     "elementId": elementId, 
     "documentId": documentId, 
     "segmentNumber": segmentId 
    } 
    let sendingData = JSON.stringify(input); 
    let urlPost = "https://localhost:44375/api/data/SendSegmentData"; 
    let output = new AsyncSubject<SegmentData>(); 
    let options = new RequestOptions({ 
     headers: headers, 
     method: RequestMethod.Post, 
     url: urlPost 
    }); 
    this.http.post(urlPost, sendingData, options) 
     .subscribe(result => { 
      output.next(result.json()); 
      output.complete(); 
     }); 
    return output; 
} 

클래스 SegmentData 클라이언트가 서버에서 관련 클래스와 동일합니다. 내 응답은 완벽하게 분석됩니다. 이 문제를 해결하는 방법? )

+0

비동기를 이해해야합니다. subscribe() 할 때 요청을 보냅니다. 그런 다음 while 루프의 나머지 코드가 즉시 실행됩니다. 훨씬 나중에 비동기 적으로 요청이 수천 킬로미터 떨어진 서버에서 처리되고 서버가 응답을 되돌려 보낸 경우 가입하기 위해 전달한 콜백 함수가 실행됩니다. 따라서 요청을 보낸 직후 응답에서 값에 액세스 할 수 없습니다. 토스터에 넣은 직후에 토스트를 먹을 수 없습니다. 토스터가 준비가되었다고 말한 후에 그것을 먹어야합니다. –

+0

감사합니다.하지만 응답이 다시 오기까지 기다리는 방법은 무엇입니까? –

+0

기다리지 마십시오. subscribe()에 전달 된 콜백 내에 응답에 대한 액세스가 필요한 코드를 넣습니다. –

답변

0

구독 호출 옆의 코드는 구독 호출이 끝날 때까지 기다리지 않고 실행되므로 while 루프는 구독이 완료되고 실행될 때까지 기다리지 않고 실행됩니다. 아래 코드는 모든 코드를 가입 호출에 배치하도록 변경되었습니다.

onGetSegmentsClick(size: number) { 
    debugger; 
    if (size > 0) { 
     let counter = 0; 
     let temporarySegment = new SegmentData(); 
     while (counter < size) { 
      this.segmentService.getSegment(counter + 1, this.elementId, this.documentId).subscribe(result => { 
       console.log("get segment request is sended"); 
       temporarySegment = result; 
       console.log("gotten message is:", result); 

      ModalComponent.segmentsCollection.push(new SegmentData()); 
      ModalComponent.segmentsCollection[ModalComponent.segmentsCollection.length - 1] = 
       ModalComponent.newer.TemporaryObjectEqualizer(temporarySegment); 
      ModalComponent.segmentsCollection[ModalComponent.segmentsCollection.length - 1].SegmentDataId = 
       counter + 1; 
      counter++; 
      }); 
     } 
    } 
} 
0

다른 사람들은 이미 무슨 일이 일어나고 있는지 설명했습니다. while 루프 내에서 subscribe() 다음에 나오는 코드는 보다 먼저 구독 함수를 실행합니다.이 함수는 서버에서 응답이 반환 된 후에 만 ​​비동기 적으로 실행되기 때문에 구독 함수입니다. 따라서 temporarySegment 값을 사용하려고 할 때 여전히 비어 있습니다.

당신은 질문 : 응답이 다시 때까지

어떻게 기다리지?

async/await 코딩 패턴을 사용하여 비동기 코드를 나머지 프로 시저와 함께 실행할 수 있습니다.

async onGetSegmentsClick(size:number){ ... 

그런 약속으로 관찰 체인을 설정하고 진행하기 전에 결과를 기다려야하는 JS 엔진을 얘기하는 await 수정을 사용합니다 : 첫 번째 함수 선언에 async에게 수정을 추가

temporarySegment = await this.segmentService.getSegment(...).toPromise(); 
// here you can use temporarySegment immediately 

See the docs

+0

답장 드리겠습니다. 늦게 나는 주기적으로 나쁜 생각으로 요청을 보내는 것을 발견했다. 그래서 모든 요청을 하나의 요청으로 응답한다. –