Angular pitfall: Multiple HTTP requests with RxJS and observable$ | async

综合技术 Novanet (源链)

I recently discovered that our Angular app was making multiple HTTP requests unintentionally to the same REST API endpoint.

The app was using the HttpClient introduced in Angular 4.3, which enables direct access to the JSON response when subscribing to the Observable from the HTTP request. The HTML markup used async pipe bindings : observable$ | async .

Just here for the code example? Click here

Reproducing the problem

To reproduce this problem, I created a sample app using StackBlitz . This app retrieves my GitHub user information and displays it.

The component:

The HTML:

This seems pretty straightforward. My name and avatar are displayed on the page. Everything is awesome.

But looking at the Chrome DevTools Network tab reveals the issue – 3 (!) HTTP requests have been made :

Needless to say, this will impact the performance, the amount of data transferred and the number of network requests.

Why is this happening

Each async pipe triggers a new HTTP request, because each result$ | async creates a new subscription/stream to the result$ Observable.

This is not a bug, but the nature of how Observables are implemented to facilitate flexibility.

You can think of the Observable result$ as a function declaration, and that each result$ | async is calling the same function.

The share operator

The solution is to make the subscribers share the underlying subscription to the Observable.

This can be done using the share operator , which ” returns an observable sequence that shares a single subscription to the underlying sequence “.

From the RxJS-documentation :

The share operator is a specialization of publish which creates a subscription when the number of observers goes from zero to one, then shares that subscription with all subsequent observers until the number of observers returns to zero, at which point the subscription is disposed.

This means that each result$ | async will share the same subscription, and only one HTTP request will be made .

Side effects

It’s important to notice that the subscription closes when the source Observable completes. This is fine for HTTP requests because you don’t need the subscription after you get the HTTP response. This can also be a pitfall, though. Even if using the share-operator, the code below will produce 3 HTTP requests because the markup inside the div is rendered after the first subscription has been closed.

Name: {{ (result$ | async)?.name }}

Cleaner HTML with template variables

For better readability replace the inner async pipes with a template variable:

The above markup will result in only one HTTP request without using the share operator, but it requires that you only access the Observable once – which is really an accident waiting to happen.

The solution

I recommend combining the share operator with template variables, which results in the following implementation for my app:

Note 1:

In a more complex solution you would probably have a separate HTTP service where the share operator is added, so you won’t have to remember it each time you create an HTTP request.

Note 2:

Angular 5.0.0/RxJS 5.5 introduced lettable operators , changing the operator import syntax to:

import { share } from 'rxjs/operators';

For earlier versions, the share operator must be imported like this:

import 'rxjs/add/operator/share' and used like this: http.get().share() .

Code example (StackBlitz)

Click EDITOR to browse the code. Click here for full screen

您可能感兴趣的

Angular如何在模板驱动表单中自定义校验器... 引言 模板驱动表单相比较响应式表单可以少更少的代码做同样的事情,可也损失了 自由度 与 更易测试 ,当然很多人并不在乎啦。 所以我相信很多人在编写Angular不自由自主去更倾向于模板驱动表单的写法。 表单最核心的是 校验体验 ,在Angular中简直就是发挥到...
Nginx 1.13.9 and HTTP/2 Server Push Here are some very exciting news from the Nginx front lines: HTTP/2 Server Push is now available in the latest and greatest Nginx 1.13.9 , which ...
Angular 1 to React Migration Reading Time: 8 minutes Recently I decided to migrate one of my side projects to React. I had several reasons for that, but the most...
5G时代,HTTP和DNS协议将如何演进? HTTP和DNS几乎已经成为家喻户晓的两种协议,但5G时代的来临,这些协议都将发生巨大的变化。 互联网在过去三十年里发展非常迅猛,这得益于两个关键协议:代表超文本传输协议的HTTP和代表域名系统的DNS。 HTTP是用于在笔记本电脑或手机上运行的Web浏览器与正在通信的网页或应用程序之间发送数据...
Angular2+ 使用 Protractor 与 Modify Header Value (HTT... 入职新公司第二周,接到了一个E2E测试的任务,两天的时间把所有的测试条件都写完了,结果剩下三天都卡在了Windows Authorization验证这里。 先说一下公司项目Authorize的逻辑 第一步,输入网址后,将重定向到公司统一的登录网站,需要Windows Authoriza...
责编内容来自:Novanet (源链) | 更多关于

阅读提示:酷辣虫无法对本内容的真实性提供任何保证,请自行验证并承担相关的风险与后果!
本站遵循[CC BY-NC-SA 4.0]。如您有版权、意见投诉等问题,请通过eMail联系我们处理。
酷辣虫 » Angular pitfall: Multiple HTTP requests with RxJS and observable$ | async



专业 x 专注 x 聚合 x 分享 CC BY-NC-SA 4.0

使用声明 | 英豪名录