【问题标题】:Angular - Sequencing Multiple HTTP RequestsAngular - 对多个 HTTP 请求进行排序
【发布时间】:2019-07-10 08:15:35
【问题描述】:

在我的 Angular 7 项目中,作为组件初始化的一部分,我正在运行一系列 HTTP 请求。每次请求后,我都会收到响应,然后运行下一个请求。

目前我已将 HTTP 请求放入服务并从我的组件中调用它们。我的 HTTP 请求函数应用了额外的 RXJS 函数,包括超时和通过 .pipe 函数重复请求。错误处理在组件中完成。

要链接,在一个请求完成后,我会在另一个函数中调用下一个请求。我将需要第一个请求的响应数据来执行下一个响应。

问题是我当前的链接方式看起来非常混乱且难以遵循。

有没有更好的方法来链接 HTTP 请求?

我知道有一个 rxjs fork 函数,但对如何实现它有点困惑,尤其是当我有错误处理和管道时。

注意:错误的处理方式与请求相同。

完整代码如下,提前致谢。

Component
formData: any;
style: any;
subscribers:any[];

constructor(private webService: WebService){}

ngOnInit(){
 let id: number = 1;
 this.getFormData(id);

}

getFormData(id: number) {
 this.webService.getFormData(id)
 .subscribe(
   data => { 
     this.formData = data;
     this.getFormStyle(this.formData.style_id);

   },
     err => {
      // Error handler
     }
  )
}

getFormStyle(id: number) {
 this.webService.getFormStyle(id)
 .subscribe(
   data => { 
     this.style = data;
     this.getFormSubscribers(this.formData.subscriber_id);

   },
     err => {
      // Error handler
     }
  )
}

getFormSubscribers(id: number) {
 this.webService.getFormSubscribers(id)
 .subscribe(
   data => { 
     this.subscribers = data;
   },
     err => {
      // Error handler
     }
  )
}

网络服务

表单数据 API

getFormData(id: number): any {
 let headers: any = this.headerService.getHeaders();
 return this.http.get('www.test.com/form/data/' + id, {headers: headers})
    .pipe(timeout(25000))
    .pipe(retryWhen(errors => errors
      .pipe(map((err, index) => {
        // No Error, throw immediately
        if (!err) {
          throw err;
        } 
        // Caught error (ie not disconnected), throw immediately
        if (err.status !== 0) {
          throw err;
        }
        // Disconnection repeat to limit
        if (index === 2) {
          throw err;
        }
        return err;
      }))
      .pipe(delay(2000))))
    .pipe(map(res => res.json()))
}

表单样式 API

getFormStyle(style_id:number) {
     let headers: any = this.headerService.getHeaders();
     return this.http.get('www.test.com/form/style/' + style_id, {headers: headers})
        .pipe(timeout(25000))
        .pipe(retryWhen(errors => errors
          .pipe(map((err, index) => {
            // No Error, throw immediately
            if (!err) {
              throw err;
            } 
            // Caught error (ie not disconnected), throw immediately
            if (err.status !== 0) {
              throw err;
            }
            // Disconnection repeat to limit
            if (index === 2) {
              throw err;
            }
            return err;
          }))
          .pipe(delay(2000))))
        .pipe(map(res => res.json()))

}

表单订阅者 API

getFormSubscribers(subscriber_id:number) {
     let headers: any = this.headerService.getHeaders();
     return this.http.get('www.test.com/form/subscribers/' + subscriber_id, {headers: headers})
        .pipe(timeout(25000))
        .pipe(retryWhen(errors => errors
          .pipe(map((err, index) => {
            // No Error, throw immediately
            if (!err) {
              throw err;
            } 
            // Caught error (ie not disconnected), throw immediately
            if (err.status !== 0) {
              throw err;
            }
            // Disconnection repeat to limit
            if (index === 2) {
              throw err;
            }
            return err;
          }))
          .pipe(delay(2000))))
        .pipe(map(res => res.json()))

}

【问题讨论】:

  • 您使用什么来进行 API 调用。 HttpHttpClient。看起来您正在使用Http,这没有意义,因为您还使用了 Rxjs 5.5 之后出现的现代 Rxjs 语法,但在此之前已弃用 Http。所以只想确认一下。是Http 还是HttpClient
  • 当您需要前一个值时,使用 switchMap 链接可观察对象。 learnrxjs.io/operators/transformation/switchmap.html
  • 我正在使用 Angular Http,但不知道它已被弃用:import { Http } from '@angular/http';

标签: angular http rxjs


【解决方案1】:

您可以尝试async await 对 api 调用进行排序。

Component
formData: any;
style: any;
subscribers:any[];

constructor(private webService: WebService){}

ngOnInit(){
 let id: number = 1;
 this.getFormData(id);

}

async getFormData(id: number) {
 this.webService.getFormData(id)
 .subscribe(
   data => { 
     this.formData = data;
     console.log('start');
     await this.getFormStyle(this.formData.style_id);
     await this.getFormSubscribers(this.formData.subscriber_id);
     console.log('end'); // this line will compile once all the await function compilation will completed.
   },
     err => {
      // Error handler
     }
  )
}

getFormStyle(id: number) {
 return new Promise ((resove, reject) => {
    this.webService.getFormStyle(id)
    .subscribe(
     data => { 
       this.style = data;
       resolve(''); // if you want to pass the data you can pass that data in to resolve 
     },
     err => {
      // Error handler
     }
  )
 })
}

getFormSubscribers(id: number) {
 return new Promise ((resolve, reject) => { this.webService.getFormSubscribers(id)
 .subscribe(
   data => { 
     this.subscribers = data;
     resolve(''); // if you want to pass the data you can pass that data in to resolve 
   },
     err => {
      // Error handler
     }
  ))
}

希望对你有帮助。

【讨论】:

  • 感谢您的解决方案。我需要知道所有响应何时完成,以便我可以运行其他初始化函数。有没有办法知道等待功能何时完成?
  • await 函数是按顺序编译的,所以如果我在 await 的和处写 console.log('end');,那么 console.log('end');将在 await 函数编译后编译。
  • awesome 不知道这一点以及我所追求的!我会放弃它,如果一切顺利的话,将作为解决方案。非常感谢
  • @KaTech 欢迎光临???
  • 完美的作品。再次感谢...我希望我能早点知道这本可以有很多更简洁的代码
猜你喜欢
  • 1970-01-01
  • 2011-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多