Can the operator pipeline generate interim observables in a manner akin to how filter, map, and reduce generate interim arrays?

I need some clarification regarding the efficiency of operator pipelines in RxJS.

Based on my current understanding, each operator within the pipeline receives an observable and generates a new (potentially modified) observable to pass on to the next operator. This process is similar to how JavaScript's filter, map, and reduce functions work, ensuring the original observable or array remains pure and untouched.

The RxJS Documentation supports this notion at: https://rxjs-dev.firebaseapp.com/guide/operators

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable. It is a pure operation: the previous Observable stays unmodified.

When dealing with lengthy operator pipelines, the creation of intermediate observables may seem resource-intensive.

Furthermore, I am currently studying the book 'Reactive Programming with RxJS 5' by Sergi Mansilla. Although RxJS has advanced to version 6.5.3, the fundamental mechanisms are likely unchanged.

The book discusses the efficiency of pipelines, stating that they do not produce intermediate Observables. Instead, all operations are applied to each element simultaneously. For instance, the operator take(amount) completes the stream after extracting the initial amount of elements. Moreover, it mentions the concept of lazy evaluation, which involves traversing the source observable stream just once or until the take condition is met.

import * as rxCore from 'https://dev.jspm.io/rxjs@6/_esm2015/index';
import * as rxOps from 'https://dev.jspm.io/rxjs@6/_esm2015/operators';

const numberStream = rxCore.range(0, 10);
numberStream.pipe(
    rxOps.map(number => number * number),     //creates Observable with [0,1,4,9,16,25,36,49,64,81]
    rxOps.filter(number => number % 2 === 0), //creates Observable with [0,4,16,36,64]
    rxOps.take(3)         //completes after [0,4,16]
).subscribe(console.log); //logs 0, 4, 16

Is there any generation of intermediate observables within this operator pipeline? Or does only the final pipeline create a new observable while leaving the numberStream unaffected? What exactly is happening in this scenario?

Answer №1

When creating a custom operator to use in the pipe() method, it is important to consider how the function will modify or append operations to the source observable.

source=>source.pipe(...) 

The custom operator should return an observable that has been modified by the additional operations applied within the function. It is worth noting that the end result of the pipe will still only have one source observable passed through.

Answer №2

It seems that nearly every RxJS operator generates a new intermediate Observable. To date, I have yet to come across an operator that does not follow this pattern, leading me to believe that it is a standard behavior for all of them.

For instance, the map() operator internally triggers the execution of the lift method. The purpose of the lift method is to create a fresh Observable and return it, designating the current Observable as the "source" Observable.

In practical terms, when you use operators like range, it initiates one Observable; meanwhile, map, filter, and take introduce three distinct Observables, each tied back to the previous one through the "source" connection. Therefore, the "source" Observable for map originates from the Observable created by range, forming a chain reaction.

Hence, upon subscribing to any given Observable, the system attempts to engage with the operator linked to the "source" Observable. For operations like map, the process unfolds by triggering its call method, which in turn subscribes to the corresponding source Observable. In practice, this subscription trickles down to the initial Observable (lacking a direct "source"), thus eluding any operator application.

Given extensive operator pipelines, creating intermediary observables might appear resource-intensive.

The good news is that Intermediate Observables consist of plain JavaScript objects, offering a lightweight structure that poses minimal performance concerns even when stacking numerous objects together. Moreover, Observables remain inert until an event prompts action, ensuring efficiency.

A section in a literature discusses pipeline efficiency, claiming that observable pipelines bypass intermediate Observable creation and instead execute operations on each element continuously.

In my view, while some validity exists in this claim, the reality is more nuanced. Operators do apply functions to individual elements, but rather than operating via a singular Observable entity, they establish multiple ones for enhanced processing. This paradigm shift appears prevalent in modern iterations of RxJS beyond version 5.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having trouble getting the Bootstrap tooltip to work on a Select option?

Is there a way to have a tooltip displayed for each option in the select box? <select ng-model="rightList" class="form-control" size="13" multiple> <option ng-repeat="item in selectedList" value="{{$ ...

Setting up parameters and arguments in Vuex mutations: A guide

I am currently developing a todo list application using Vue.js, Vuex, and Firebase. The functionality of the app seems to be in working order with the Store file effectively managing the retrieval and display of entered todo items to and from Firestore. Ho ...

What is the best way to choose a specific row with Enzyme?

We have chosen Jest for doing UI Test-Driven Development on our React application. Our component rendering structure looks like this: <Div> <Row> </Row> <ROW> <Row> <ROW> <Link> <Link> ...

What are some ways to conceal the API connection within a button?

I have a code that allows me to perform a certain API call with a link. Here is an example: <a class="btn btn-default" href="https://testapi.internet.bs/Domain/Transfer/Initiate?ApiKey='.$user.'&Password='.$pass.'&Domain=&ap ...

Should we employ getAttribute() or avoid it entirely? That is the ultimate query

Similar Topic: JavaScript setAttribute vs .attribute= javascript dom, how to handle "special properties" as versus attributes? On multiple occasions, I've encountered criticism in forums or Usenet about the way I access attributes i ...

The variable 'props' is given a value but is never utilized - warning about unused variables in Vue 3

Within my Vue component file, I am using the following code: <template> <router-link :to="{ name: routerName }" type="is-primary" class="inline-flex justify-center py-2 px-3 mb-3 border border-transparent shado ...

Inject a dynamic URL parameter into an iframe without the need for server-side scripting

I'm really stuck and could use some assistance with the following issue, as I am unable to solve it on my own :( When a user is redirected to a form (provided via an iframe), there is a dynamic URL involved: website.com/form?id=123 The code resp ...

In the realm of JavaScript, removing a DOM element can sometimes feel like an

For my project, I am using JavaScript, DOM, and AJAX to create pages. I am trying to figure out how to check if an element already exists and, if it does, remove it. This is what I have tried: var elementL = document.getElementById('divLogin'); ...

Having trouble getting an HTML form to work when making a PHP and Ajax request

I am trying to validate an HTML form using Ajax to prevent the browser from loading the page. Ideally, when a user enters their first name, it should display above the HTML form. However, I am encountering an issue where it is not showing up as expected... ...

Should the secret for express-session be a fixed value or should it change dynamically?

I'm uncertain whether the secret for this application should remain static or if it can be dynamic. Currently, I am setting the secret as follows: var salt1 = bcrypt.genSaltSync(); var salt2 = bcrypt.genSaltSync(); var secret = bcrypt.hashSync(salt1 ...

Steps to successfully set up a React application without encountering any installation errors

Hey everyone, I've been trying to install React on my system for the past two days but keep encountering errors. Initially, I used the commands below to install the React app and it worked smoothly: 1. npm install -g create-react-app 2. create-react- ...

What is the best way to extract the value from a Material UI Slider for utilization?

I am looking to capture the value of the slider's onDragStop event and store it as a const so that I can use it in various parts of my code. However, I am unsure about how to properly declare my const sliderValue and update it. Any guidance on where a ...

Proper method of defining an action in Vuex

Do you think it's sufficient to create vuex-actions as simple as a1, without chaining then/catch calls? Or should I always go with creating Promises as in a2 (and also adding a reject branch)? Appreciate your insights... import Vue from 'vue& ...

Error in electron-builder: Module 'dmg-license' was not found

Seeking a straightforward method to create an electron app for macOS from a Linux machine. Unfortunately, the electron-builder -m command is not functioning properly. Here is the complete output of the command: electron-builder -m • elec ...

Designing dynamic SVG elements that maintain uniform stroke widths and rounded edges

I'm currently tackling a project that involves creating SVG shapes with strokes that adjust responsively to the size of their parent container. My aim is for these shapes to consistently fill the width and height of the parent container, and I intend ...

Insert a new <tr> element into a dynamic table using PHP and jQuery without the need to refresh the page

I am attempting to dynamically insert a row into an existing table when a button is clicked. The rows in the table are created dynamically based on data retrieved from a PHP script. My approach involves making an ajax call to the insert_tr.php script, whi ...

Can Regex expressions be utilized within the nodeJS aws sdk?

Running this AWS CLI command allows me to retrieve the correct images created within the past 45 days. aws ec2 describe-images --region us-east-1 --owners self -- query'Images[CreationDate<`2021-12-18`] | sort_by(@, &CreationDate)[].Name&apos ...

Tips for alternating the color of <li> or <tr> elements consecutively

Looking to alternate the background color of li or tr elements consecutively. Please note: A static class will not work as I need to call this in a while loop. The desired output should look like: <li>line1</li> //white background <li> ...

CSS - owl carousel automatically stretches images to full width

Here is the code snippet that I am working with: $(document).ready(function() { $('.owl-carousel').owlCarousel({ loop:true, items:4, autoplay:true, autoplayTimeout:2000, autoplayHoverPause:true }); }); #owl-demo ...

The GAS web application is experiencing issues with sorting dates correctly on the Javascript table

I have a food consumption log in a table that I need to sort. When I attempt to sort by the date column, I notice an issue with how it groups numbers together. For example, the sorting places all dates starting with 10 between 1 and 2, then all dates star ...