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

谢谢你回答。后者我发现发送请求的周期不好主意,所以只需要在一个请求中获取所有数组作为响应。 –