2017-11-11 14 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

サブスクライブの次のコードは、サブスクライブが終了するのを待つことなく実行されますが、ループはサブスクライブが完了して実行されるのを待たずに実行されます。以下のコードを変更して、すべてのコードを購読呼び出し内に配置します。

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修飾子を追加します。

async onGetSegmentsClick(size:number){ ... 

は、その後の約束に観察可能なチェーンをオンにして先に進む前に、結果を待つためにJSエンジンを伝えるためにawait修飾子を使用します。

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

See the docs

+0

お返事ありがとうございました。後半私はサイクルの悪い考えでリクエストを送信していることが分かったので、ただ一つのリクエストですべての配列を応答として取得してください。 –

関連する問題