如何在Angular 2中链式调用HTTP请求?

27 浏览
0 Comments

如何在Angular 2中链式调用HTTP请求?

我对Angular 2和HTTP Observables不太熟悉。我有一个组件调用一个HTTP服务并返回一个Observable。然后我订阅该Observable,一切都正常。

现在,我希望在该组件中,在调用第一个HTTP服务后,如果调用成功,调用另一个HTTP服务并返回该Observable。因此,如果第一个调用不成功,组件将返回该Observable,否则返回第二个调用的Observable。

如何最好地链接HTTP调用?是否有一种优雅的方式,例如像monads这样的方式?

0
0 Comments

问题的出现原因:文章中提到,在使用Angular 8时,作者花了很长时间去学习mergeMap和forkJoin等操作符的使用,尝试在一个HTTP调用的响应中为每个元素进行另一个HTTP调用,但是在与同事讨论后,他们更喜欢使用简单的async/await方式来提高代码的可读性。作者认为简单的async/await方式比rxjs更简单。

解决方法:文章中给出了使用async/await方式进行HTTP调用链的示例代码。首先,定义了一个async函数getContrat(),在这个函数中使用了await关键字来等待每个HTTP调用的响应。然后,可以通过调用这个函数来使用返回的结果。另外,文章还提到了使用try/catch来处理错误的方法。

整理成的文章如下:

使用Angular 2中的rxjs如何进行HTTP调用链?

在Angular 8中,我们可以使用rxjs来实现HTTP调用链。但是,这种方法易于阅读吗?我不确定。在我看来,一种更可读的替代方法是使用await/async。

下面是一个示例代码:

async getContrat(){
    // 获取客户信息
    const customer = await this.http.get('./customer.json').toPromise();
    // 通过URL获取合同信息
    const contract = await this.http.get(customer.contractUrl).toPromise();
    return contract; // 在这里可以返回任何你想要的结果
}

然后进行调用:

this.myService.getContrat().then( (contract) => {
  // 在这里进行你想要的操作
});

或者在一个async函数中使用:

const contract = await this.myService.getContrat();

你还可以使用try/catch来处理错误:

let customer;
try {
  customer = await this.http.get('./customer.json').toPromise();
}catch(err){
   console.log('在获取客户信息时发生错误');
   throw err; // 传播错误
   //customer = {};  // 这是一种可能的情况
}

花了很长时间继续使用mergeMap和forkJoin的示例来尝试在Angular 8中实现在另一个HTTP调用的响应中为每个元素进行另一个HTTP调用,但在与同事讨论后,他们更喜欢使用简单的async/await方式来提高代码的可读性。不要为了使用响应式函数而陷入过度工程的兔子洞,这种方式比rxjs更简单。我更喜欢这种方式。

参考链接:https://stackoverflow.com/questions/37576685

0
0 Comments

Angular 2中的问题:如何在Angular 2中链接多个HTTP调用?

原因:在Angular 2中,我们经常需要在一个HTTP调用完成后执行另一个HTTP调用。这通常发生在我们需要根据第一个HTTP调用的结果来确定第二个HTTP调用的URL时。但是,直接在第一个HTTP调用的回调函数中执行第二个HTTP调用会导致代码结构不清晰,难以维护和扩展。

解决方法:可以使用RxJS的mergeMap操作符来解决这个问题。具体方法取决于所使用的Angular版本和RxJS版本。

对于Angular 4.3+和RxJS 6+,使用HttpClientModule,可以按照以下方式链接多个HTTP调用:

import { mergeMap } from 'rxjs/operators';
this.http.get('./customer.json').pipe(
  mergeMap(customer => this.http.get(customer.contractUrl))
).subscribe(res => this.contract = res);

对于Angular版本小于4.3和RxJS版本小于5.5,使用HttpModule,可以按照以下方式链接多个HTTP调用:

import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/mergeMap';
this.http.get('./customer.json')
  .map((res: Response) => res.json())
  .mergeMap(customer => this.http.get(customer.contractUrl))
  .map((res: Response) => res.json())
  .subscribe(res => this.contract = res);

以上是通过使用mergeMap操作符来链接多个HTTP调用的方法。更多关于mergeMap操作符的详细信息可以在这里找到。

在Angular 2.0(beta 0)中,需要导入`rxjs/add/operator/map`和`rxjs/add/operator/mergeMap`,以便使用这些操作符。

有人可能会问,如果使用flatMap为什么还要导入mergeMap?事实上,flatMap是mergeMap的别名。但是,由于导入和使用的方式不同,这可能会导致代码不够明显,从而引发更多的问题和疑问。

如果想更好地理解mergeMap/flatMap操作符,可以在这里找到一个很好的教程。

通过上述方法,我们可以在Angular 2中链式调用多个HTTP请求,使代码更加清晰和易于维护。

0