【转】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 ...
随机推荐
- PHP实现的MongoDB数据增删改查
原文地址:https://www.mongodb.org.cn/drivers/2.html (该网站为mongoDB官方网站) php中使用mongodb你必须使用 mongodb 的 php驱 ...
- 【Linux开发】【CUDA开发】Ubuntu上安装NVIDIA显卡驱动
机型为戴尔Vostro3900 显卡型号为GTX 745 对于Nvidia显卡的驱动,如今很多Linux发行版会默认使用名为nouveau的驱动程序.Nouveau是由第三方为Nvidia开发的一 ...
- 利用function和bind实现回调功能
介绍一种利用function和bind来实现回调的功能. C++参考手册中对function的介绍: std::function的实例能存储.复制及调用任何可调用的目标,包括:函数.lambda表达式 ...
- 【剑指offer】面试题 31. 栈的压入、弹出序列
面试题 31. 栈的压入.弹出序列 NowCoder LeetCode 题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如 ...
- 11 Reponse对象+ServletContext对象
1.HTTP协议: (1)请求消息:客户端发送给服务器端的数据 数据格式: 1. 请求行 2. 请求头 3. 请求空行 4. 请求体 (2)响应消息:服务器端发送给客户端的数据 * 数据格式: 1. ...
- pyenv基本使用
pyenv使用 1.安装: git clone https://github.com/pyenv/pyenv.git 2.配置pyenv环境变量 echo 'export PYENV_ROOT=&qu ...
- spark 预编译安装
1.下载地址: http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-3.0.0-preview/spark-3.0.0-preview-bin ...
- 【C#】上机实验九
1. 设计一个Windows登陆窗体应用程序,能够实现根据现有表中数据模拟登陆,并设置相关属性,具体界面如下. 可能使用到的类: (1)SqlConnection (2)SqlCommand (3)S ...
- SpringCloud——eureka集群
目的: 第一种普通方式 第二种方式骚操作 Eureka自我保护机制 Eureka集群搭建 说的通俗易懂一点就是,同一个项目部署在多个服务器上. 当注册中心扛不住高并发的时候,这时候 要用集群来扛: 今 ...
- 一行代码让3D翻转后的文本恢复清晰
FlashPlayer10提供的3D功能有一个相当蛋疼的问题:只要设置过rotationX.rotationY或者rotationZ属性,显示对象里面的文字(尤其是设备字体,位图文本)就会一直处于模糊 ...