原文:https://coryrylan.com/blog/angular-multiple-http-requests-with-rxjs
---------------------------------------------------------------
Cory Rylan

Nov 15, 2016 
Updated Feb 25, 2018 - 5 min readangular rxjs

This article has been updated to the latest version of Angular 7. The content is still likely be applicable for Angular 2 or other previous versions.

This article has been updated to use the new RxJS Pipeable Operators which is the new default for RxJS 6.

A typical pattern we run into with single page apps is to gather up data from multiple API endpoints and then display the gathered data to the user. Fetching numerous asynchronous requests and managing them can be tricky but with the Angular’s Http service and a little help from the included RxJS library, it can be accomplished in just a few of lines of code. There are multiple ways to handle multiple requests; they can be sequential or in parallel. In this post, we will cover both.

Let’s start with a simple HTTP request using the Angular Http service.

import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: 'app/app.component.html' }) export class AppComponent { constructor(private http: HttpClient) { } ngOnInit() { this.http.get('/api/people/1').subscribe(json => console.log(json)); } } 

In our app, we have just a single component that pulls in Angular’s Http service via Dependency Injection. Angular will give us an instance of the Http service when it sees the signature in our component’s constructor.

Now that we have the service we call the service to fetch some data from our test API. We do this in the ngOnInit. This is a life cycle hook where its ideal to fetch data. You can read more about ngOnInit in the docs. For now, let’s focus on the HTTP call. We can see we have http.get() that makes a GET request to /api/people/1. We then call subscribe to subscribe to the data when it comes back. When the data comes back, we just log the response to the console. So this is the simplest snippet of code to make a single request. Let’s next look at making two requests.

Subscribe

In our next example, we will have the following use case: We need to retrieve a character from the Star Wars API. To start, we have the id of the desired character we want to request.

When we get the character back, we then need to fetch that character’s homeworld from the same API but a different REST endpoint. This example is sequential. Make one request then the next.

Angular Form Essentials

Learn the essentials to get started creating amazing forms with Angular, get the E-Book now!

import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-root', templateUrl: 'app/app.component.html' }) export class AppComponent { loadedCharacter: {}; constructor(private http: HttpClient) { } ngOnInit() { this.http.get('/api/people/1').subscribe(character => { this.http.get(character.homeworld).subscribe(homeworld => { character.homeworld = homeworld; this.loadedCharacter = character; }); }); } } 

Looking at the ngOnInit method, we see our HTTP requests. First, we request to get a user from /api/user/1. Once loaded we the make a second request a fetch the homeworld of that particular character. Once we get the homeworld, we add it to the character object and set the loadedCharacter property on our component to display it in our template. This works, but there are two things to notice here. First, we are starting to see this nested pyramid structure in nesting our Observables which isn’t very readable. Second, our two requests were sequential. So let’s say our use case is we just want to get the homeworld of our character and to get that data we must load the character and then the homeworld. We can use a particular operator to help condense our code above.

MergeMap

In this example, we will use the mergeMap operator. Let’s take a look at the code example first.

import { Component } from '@angular/core'; import { Http } from '@angular/http'; import { Observable } from 'rxjs/Observable'; import { mergeMap } from 'rxjs/operators'; @Component({ selector: 'app-root', templateUrl: 'app/app.component.html' }) export class AppComponent { homeworld: Observable<{}>; constructor(private http: HttpClient) { } ngOnInit() { this.homeworld = this.http.get('/api/people/1').pipe( mergeMap(character => this.http.get(character.homeworld)) ); } } 

In this example, we use the mergeMap also known as flatMap to map/iterate over the Observable values. So in our example when we get the homeworld, we are getting back an Observable inside our character Observable stream. This creates a nested Observable in an Observable. The mergeMap operator helps us by subscribing and pulling the value out of the inner Observable and passing it back to the parent stream. This condenses our code quite a bit and removes the need for a nested subscription. This may take a little time to work through, but with practice, it can be a handy tool in our RxJS tool belt. Next, let’s take a look at multiple parallel requests with RxJS.

ForkJoin

In this next example, we are going to use an operator called forkJoin. If you are familiar with Promises, this is very similar to Promise.all(). The forkJoin() operator allows us to take a list of Observables and execute them in parallel. Once every Observable in the list emits a value, the forkJoin will emit a single Observable value containing a list of all the resolved values from the Observables in the list. In our example, we want to load a character and a characters homeworld. We already know what the ids are for these resources so we can request them in parallel.

import { Component } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs/Observable'; import { forkJoin } from "rxjs/observable/forkJoin"; @Component({ selector: 'app-root', templateUrl: 'app/app.component.html' }) export class AppComponent { loadedCharacter: {}; constructor(private http: HttpClient) { } ngOnInit() { let character = this.http.get('https://swapi.co/api/people/1'); let characterHomeworld = this.http.get('http://swapi.co/api/planets/1'); forkJoin([character, characterHomeworld]).subscribe(results => { // results[0] is our character // results[1] is our character homeworld results[0].homeworld = results[1]; this.loadedCharacter = results[0]; }); } } 

In our example, we capture the character and characterHomeworld Observable in variables. Observables are lazy, so they won’t execute until someone subscribes. When we pass them into forkJoin the forkJoin operator will subscribe and run each Observable, gathering up each value emitted and finally emitting a single array value containing all the completed HTTP requests. This is a typical pattern with JavaScript UI programming. With RxJS this is relatively easy compared to using traditional callbacks.

With the mergeMap/flatMap and forkJoin operators we can do pretty sophisticated asynchronous code with only a few lines of code. Check out the live example below!

转载于:https://www.cnblogs.com/oxspirt/p/10858879.html

Angular Multiple HTTP Requests with RxJS相关推荐

  1. Angular中优雅的处理RxJs自动取消订阅的方式以免出现内存泄露以及多次调用的问题

    Angular中深度集成了Rxjs,只要你使用Angular框架,你就不可避免的会接触到RxJs相关的知识. 在Android开发中,绝大多数的Android开发者都用过RxJava.RxAndroi ...

  2. Angular multiple binding debug

    Created by Wang, Jerry, last modified on Jun 06, 2016 要获取更多Jerry的原创文章,请关注公众号"汪子熙":

  3. rxjs angular_RxJS和Angular —像专业人士一样退订

    rxjs angular All the patterns you will ever need to subscribe and unsubscribe from RxJS Observables ...

  4. angular之Rxjs异步数据流编程入门

    Rxjs介绍 参考手册:https://www.npmjs.com/package/rxjs 中文手册:https://cn.rx.js.org/ RxJS 是 ReactiveX 编程理念的 Jav ...

  5. 通过一个最简单的例子,理解Angular rxjs里的Observable对象的pipe方法

    源代码: import { of } from 'rxjs'; import { Injectable } from '@angular/core'; import { map } from 'rxj ...

  6. angular RxJs

    文章目录 说明 概念理解 观察者模式 可观察对象 subject BehaviorSubject ReplaySubject 操作符及辅助方法 range(辅助方法) map(操作符) from(辅助 ...

  7. Angular响应式开发中报错Property 'map' does not exist on type 'Observable'.引用rxjs也没用。

    Angular响应式开发源代码如下: import { Component, OnInit } from '@angular/core'; import {Observable} from 'rxjs ...

  8. angular之RXJS

    angular知识碎点之RXJS rxjs可以让你用响应式编程的方式打造一个异步的,逻辑清晰的,易于管理的业务逻辑模块 angular模块可以理解是一组具有相对独立功能的文件的集合,模块把它的执行文件 ...

  9. angular面试题及答案_关于最流行的Angular问题的StackOverflow上的48个答案

    angular面试题及答案 by Shlomi Levi 通过Shlomi Levi 关于最流行的Angular问题的StackOverflow上的48个答案 (48 answers on Stack ...

最新文章

  1. halcon模板匹配——转化算子vector_angle_to_rigid和affine_trans_contour_xld
  2. Java/Android中实现Shell命令
  3. 远程网络安装RHEL5
  4. lambda表达式对比
  5. 图片 button 去背景色_不会PS没关系,用Word更换证件照背景色只要10秒!
  6. Colourshell:给 shell 命令着色
  7. 写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理
  8. E WORD 0410
  9. 解决:蓝奏云下载链接没法打开问题
  10. bootstrap多文件上传和单文件上传
  11. 将域名解析到空间服务器,如何把域名解析到空间
  12. Service Mesh 框架选型对比分析:Linkerd、Envoy、Istio、Conduit
  13. 信号量(sem)学习笔记
  14. 爬虫大作业~以爬取hao123漫画为例
  15. 巴特沃斯(Butterworth)滤波器 (2) - 双线性变换
  16. 从后端开发转大数据开发怎么样?
  17. 解决JPEGImageEncoder生成的图片全黑的问题
  18. 85-决策树解决回归问题
  19. 【排序专训】练习题 士兵站队(中位数应用) 解题报告
  20. 不同BMP位图与调色板分析

热门文章

  1. golang gin框架入门教程,gin框架脚手架,开箱即用
  2. 1051 复数乘法 (15 分)借鉴C++ PAT (Basic Level) Practice
  3. 2022年版中国新能源公交车行业发展方向预测与投资规划建议报告
  4. java云接口_华为云JavaAPI调用数据设备接口(虚拟设备)
  5. BotVS趋势交易策略-MACD
  6. 虚拟机文件格式详解 .VMX .VMSD .VMDK .NVRAM .VMX.LCK
  7. 程序员2016年5月:走进VR开发世界
  8. SHELL中if的使用
  9. 23考研——同等学力申硕一览表!
  10. 瑞萨RL78\G13编译出现Segment ‘@@CODEL‘ can‘t allocate to memory