2017-11-11 116 views
0

我有一些Post方法的問題。我總是在我的temporarySegment中獲得空的segmentdata對象。我用數字做同樣的方式,這是工作。變量導致訂閱是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

您需要了解異步。當你訂閱()時,你發送一個請求。然後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()的代碼實際上在之前運行subscribe函數,因爲該函數僅在響應從服務器返回後異步運行。所以當你嘗試使用temporarySegment的值時,它仍然是空的。

你問:

如何要等到響應回來?

您可以使用async/await編碼模式使您的異步代碼與您的其他程序一致運行。首先添加async的修飾你的函數聲明:

async onGetSegmentsClick(size:number){ ... 

然後轉動觀察到鏈到一個承諾,並使用await修飾符告訴JS引擎,然後再繼續等待結果:

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

See the docs

+0

謝謝你回答。後者我發現發送請求的週期不好主意,所以只需要在一個請求中獲取所有數組作爲響應。 –