Javascript 如何在RXJS订阅中实现While循环

Javascript 如何在RXJS订阅中实现While循环,javascript,angular,typescript,rxjs,Javascript,Angular,Typescript,Rxjs,我有一个Angular代码,我试图订阅我的第一个api,并在此订阅中实现一个while循环。此外,我需要订阅while循环中的另一个api。原因-->我需要多次订阅内部api,while循环应该根据内部api返回的标志结束。我尝试实现下面的功能,但它不起作用。我需要一些帮助 CallBanyanToFetchQuotes() { const url1 = 'http://ws.integration.banyantechnology.com/services/api/rest/Impor

我有一个Angular代码,我试图订阅我的第一个api,并在此订阅中实现一个while循环。此外,我需要订阅while循环中的另一个api。原因-->我需要多次订阅内部api,while循环应该根据内部api返回的标志结束。我尝试实现下面的功能,但它不起作用。我需要一些帮助

CallBanyanToFetchQuotes() {
    const url1 = 'http://ws.integration.banyantechnology.com/services/api/rest/ImportForQuote';

    this.http.post(url1, payload)
      .subscribe(importForQuoteResponse => {
        this.importForQuoteResponse = importForQuoteResponse;
        console.log('LoadID = ' + this.importForQuoteResponse.Load.Loadinfo.LoadID);
        this.loadId = this.importForQuoteResponse.Load.Loadinfo.LoadID;

        while (!this.ratingCompleted) {
          const url2 = 'http://ws.integration.banyantechnology.com/services/api/rest/GetQuotes';

          this.http.post(url2, payload)
            .subscribe(getQuoteResponse => {
              this.getQuoteResponse = getQuoteResponse;
              if (this.getQuoteResponse.RatingCompleted === true) {
                this.ratingCompleted = true;
              }
            });
        }
      });
  }
中国的“傻瓜榜样”

before代码可以这样解释:我们发布了第一篇文章,但是,我们不想要这个订阅,所以我们将这个订阅更改为计时器(switchMap)。但我们不想要计时器,否则就需要第二个帖子(另一个开关图)。每次执行计时器时,第二个post都会执行,我们使用tap获得响应。我们在响应为false(takeWhile)时进行调用-重要的是使takeWhile(…,true),“true”使返回最后一个值-并过滤响应(筛选器),因此只有在响应为true时才获取“subscribe”


注意:我使用定时器(01000)每1000毫秒进行一次呼叫,可以随意更改间隔

您可以使用
扩展
模拟while循环
expand
立即将输入传递到目标,映射到可观察对象,并将其输出作为下一个输入接收。映射到
EMPTY
以结束此递归

//如果URL是静态的,则将其移出函数
常量url1=http://ws.integration.banyantechnology.com/services/api/rest/ImportForQuote';
常量url2=http://ws.integration.banyantechnology.com/services/api/rest/GetQuotes';
callBanyanToFetchQuotes(){
this.http.post(url1,有效负载).pipe(
//处理来自url1 http请求的响应
点击(导入或引用响应=>{
this.importForQuoteResponse=importForQuoteResponse;
console.log('LoadID='+this.importForQuoteResponse.Load.Loadinfo.LoadID);
this.loadId=this.importForQuoteResponse.Load.Loadinfo.loadId;
}),
//切换到url2 http请求
switchMap(=>this.http.post(url2,有效负载))
//如果评级不完整,请再次执行url2请求,或使用EMTPY结束执行
展开(quoteResponse=>quoteResponse.RatingCompleted?空:this.http.post(url2,有效负载))
//处理来自url2请求的响应
).订阅(quoteResponse=>{
this.getQuoteResponse=quoteResponse;
如果(quoteResponse.RatingCompleted==真){
this.ratingCompleted=真;
}
});
}

expand
方法保证下一个http调用将直接进行,并且只有在您收到前一个http调用的响应后才能进行。

根据所需的行为,可以使用
mergeMap
concatMap
来代替内部
开关映射
。如果
timer
发出的http请求比内部http请求更快,则使用
switchMap
响应您的上一个请求将被取消,使用
mergeMap
多个请求将同时挂起,使用
concatMap
仅在上一个请求完成后才会发出下一个请求。
this.http.post(url1, payload).pipe(
   switchMap(importForQuoteResponse=>{
      this.importForQuoteResponse = importForQuoteResponse;
      this.loadId = this.importForQuoteResponse.Load.Loadinfo.LoadID;
      return timer(0,1000).pipe(
         switchMap(()=>this.http.post(url2, payload)),
         tap(res=>this.getQuoteResponse=res),
         takeWhile(res=>!res.RatingCompleted,true),
         filter(res=>res.RatingCompleted === true)
      )
   })).subscribe(()=>{
     this.ratingCompleted = true;
   })