【转】Deep dive into pipe function in RxJS
原文: https://codewithstyle.info/deep-dive-pipe-function-rxjs/
------------------------------------------------------------
Version 5 of RxJS introduced the concept of lettable (also known as pipeable) operators. Version 6 went one step further and deprecated the old way of calling operators (method chaining). You might have already used the pipe
function. But do you really understand what it does?
Composing functions
RxJS is often called a functional-reactive programming library. It should not come as a surprise that you will find many functional programming inspirations in it. One of them is the pipe
function. Take a look at the below piece of code:
const getElement = |
The logElementValue
function takes an id
and logs to the console the value of the element with provided id
. Can you see a pattern in this function’s implementation? Firstly, it calls getElement
with id
and stores the result in el
. Next, the result is passed to getValue
which produces a new result, el
. Finally, el
is passed to console.log
. What this function does is simply taking the result of a function and passing it as an argument to another function. Is there a better, more concise way to implement this function? Let’s say we just have two functions (getElement
and getValue
). We will implement a generic function called compose
that will pass the result of getElement
to getValue
.
const compose = (f, g) => x => g(f(x)); |
The definition is very simple but may take a moment to parse. We’ve defined a function that takes two functions f
and g
(that would be getElement
and getValue
in our case) and returns a new function. This new function will take an argument, pass it to f
and then pass the result to g
. That’s exactly what we need! Now I can rewrite logElementValue
:
function logElementValue(id) { |
How about more than two functions?
But, wait! Once we have the result of calling getValueFromId
we immediately pass it to console.log
. So it’s the same pattern here. We could write it like this:
function logElementValue(id) { |
But life would be much simpler if compose
could take any number of functions. Can we do this? Sure:
const composeMany = (...args) => args.reduce(compose); |
Another brain teaser! composeMany
takes any number of functions. They are stored in args
array. We reduce
over args
composing every function with the result of composing previous functions. Anyway, the results is a function that takes any number of functions and will pass the result of N-th
function to (N+1)-th
function. But what have we achieved by that?
function logElementValue(id) { |
Which can be simplified even more:
const logElementValue = composeMany(getElement, getValue, console.log); |
Isn’t that cool? We have significantly simplified the code. It’s now very clear what logElementValue
does. And by the way - composeMany
is just a name a came up with. The official name is pipe
!
const logElementValue = pipe(getElement, getValue, console.log); |
Back to RxJS
Let’s take an example of pipe
usage in RxJS.
number$.pipe( |
We can also write it in a different way:
const { pipe } = rxjs; const transformNumbers = pipe( |
And the result is exactly the same! As you can see, the pipe
function in RxJS behaves in exactly the same way that the pipe
function that we’ve defined in the first part of the article. It takes a number of functions and composes them by passing the result of a function as an argument to another function. You might say that this is different than the previous example because here we’re invoking map
and filter
and not simply passing them. Actually, both map
and filter
will return functions. We’re not composing map
and filter
themselves but rather the functions returned by invoking them. You can check out how RxJS implements pipe
function here.
Pipeline operator
Our function is such a useful concept that it might be added as a separate operator to the JavaScript language! It would mean that the example from the previous article can be written in an even simpler way:
const logElementValue = getElement |> getValue |> console.log; |
You can see the details of the proposal here.
Summary
I hope this article helped you understand what pipe
function is all about. You should now feel more comfortable using it! The fact that RxJS migrated from the traditional, object-oriented approach of applying operators to the pipeline approach shows how strong the influence of functional programming is nowadays. I think that’s great! Let me know in comments if you prefer pipe
function to traditional method chaining.
【转】Deep dive into pipe function in RxJS的更多相关文章
- [RxJS] Chain RxJS Operators Together with a Custom `pipe` Function using Array.reduce
Instead of writing complex operators, it's usually best to write simple, single-purpose operators th ...
- X64 Deep Dive
zhuan http://www.codemachine.com/article_x64deepdive.html X64 Deep Dive This tutorial discusses some ...
- 《Docker Deep Dive》Note - Docker 引擎
<Docker Deep Dive>Note Docker 引擎 1. 概览 graph TB A(Docker client) --- B(daemon) subgraph Docker ...
- Deep Dive into Neo4j 3.5 Full Text Search
In this blog we will go over the Full Text Search capabilities available in the latest major release ...
- Deep Dive into Spark SQL’s Catalyst Optimizer(中英双语)
文章标题 Deep Dive into Spark SQL’s Catalyst Optimizer 作者介绍 Michael Armbrust, Yin Huai, Cheng Liang, Rey ...
- 《Docker Deep Dive》Note - 纵观 Docker
<Docker Deep Dive>Note 由于GFW的隔离,国内拉取镜像会报TLS handshake timeout的错误:需要配置 registry-mirrors 为国内源解决这 ...
- 重磅解读:K8s Cluster Autoscaler模块及对应华为云插件Deep Dive
摘要:本文将解密K8s Cluster Autoscaler模块的架构和代码的Deep Dive,及K8s Cluster Autoscaler 华为云插件. 背景信息 基于业务团队(Cloud BU ...
- vue3 deep dive
vue3 deep dive vue core vnode vue core render / mount / patch refs https://www.vuemastery.com/course ...
- A Deep Dive Into Draggable and DragTarget in Flutter
https://medium.com/flutter-community/a-deep-dive-into-draggable-and-dragtarget-in-flutter-487919f6f1 ...
随机推荐
- 【Python学习之九】模块
环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.模块的使用和安装模块和C语言中的头文件以及Ja ...
- 日志收集系统ELK搭建
一.ELK简介 在传统项目中,如果在生产环境中,有多台不同的服务器集群,如果生产环境需要通过日志定位项目的Bug的话,需要在每台节点上使用传统的命令方式查询,这样效率非常低下.因此我们需要集中化的管理 ...
- 移动测(APP)试与web端测试的区别
1.操作环境不同 移动端的测试环境是安卓操作环境或者iOS操作系统: web端操作环境一般是windows(如果你用的是MC电脑,那就是iOS操作系统). 2.页面的显示尺寸不同 移动端的尺寸比较多, ...
- LeetCode 556. 下一个更大元素 III(Next Greater Element III)
556. 下一个更大元素 III 556. Next Greater Element III 题目描述 给定一个 32 位正整数 n,你需要找到最小的 32 位整数,其与 n 中存在的位数完全相同,并 ...
- session知识点小结
Session: 1. 概念:服务器端会话技术,在一次会话的多次请求间共享数据,将数据保存在服务器端的对象HttpSession中. 2. 快速入门: 1. 获取HttpSession对象: Http ...
- libevent实现对管道的读写操作
读管道: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/t ...
- vue中指令绑定的v-if逻辑结构
<!-- if判断 --> <div id="app2"> <p v-if="seen"> <!-- 给p标签绑定指令 ...
- 关于TI公司DSP工程调用DELAY_US()进入非法中断问题的解决
最近笔者在调试一个DSP程序时,发现在ad外设初始化时无法正常执行,单步检查,发现当执行到调用 DELAY_US(1000);语句时,就跳入非法. 进一步追查,DELAY_US()是宏定义函数,在笔者 ...
- 摘要 - Digest
首先从md5说起,一般新进入开发行业最先接触的就是md5了,md5本质上是一个hash(谐音:哈希)算法,可以从一个大文件信息中提取出一小段信息,叫提取摘要,有的地方也有提取指纹这种说法,其实指纹这个 ...
- Unity性能优化-音频设置
没想到Unity的音频会成为内存杀手,在实际的商业项目中,音频的优化必不可少. 1. Unity支持许多不同的音频格式,但最终它将它们全部转换为首选格式.音频压缩格式有PCM.ADPCM.Vorbis ...