0.3.0 • Published 6 years ago

fast-observables v0.3.0

Weekly downloads
1
License
MIT
Repository
github
Last release
6 years ago

Fast-Observables

fast-observables is a 1kb implementation of observables inspired by zen-observable and RxJS. It started out as a simple experiment on how to write the smallest Observable library and make it as performant as possible.

Current state

Test NameRxJSzen-observablefast-observables
map603,187.444589,813.465634,546.355
filter445,687.677450,715.611521,233.32
scan358,440.041477,616.099520,379.83
take382,615.755463,212.925520,323.069
flatMap405,864.99227,595.825449,218.794

Note: Measured in operations per second (ops/s). Moreover I didn't measure async operators because they are really difficult to compare to each other due to the reliance on timers.

Installation

# npm
npm install --save fast-observables

# yarn
yarn add fast-observables

Usage

If reactive-programming is completely new to you, the official RxJS-docs have a great introduction. These links might also be helpful to crasp the basic concept of Observables:

Let's continue! The api of fast-observables is pretty similar to RxJs and zen-observable. If you've used any of these you can easily jump right in.

import { Observable } from "fast-observables";

// For any objects
Observable.of(1, 2, 3)
  .subscribe(x => console.log(x))
// => 1, 2, 3

// For any object that implements `Symbol.iterator` like arrays for example
Observable.from([1, 2, 3])
  .subscribe(x => console.log(x))
// => 1, 2, 3

Note that fast-observables follows the composition pragma (or as the RxJs folks like to call it: lettable operators). In a nutshell this means that observables can be transformed by applying various transformation functions with the pipe method.

import { Observable, map } from "fast-observables";

Observable.of(1, 2, 3)
  .pipe(
    map(x => x + x),
    map(x => x + 1),
  )
  .subscribe(x => console.log(x))
// => 3, 5, 7

Operators

A few handy operators come built-in. If you feel like something is missing, please open an issue. In case you need a custom one, have a look at the source on how to write your own. Due to functional composition it is really straightforward to implement custom operators.

NameDescription
changed()changed((prev,x) => prev !== x))Only emit next value if the value is different from the previous one
debounce(n)Only emit the last value and delay it by n ms
delay(n)Delay emitting of each value by n ms
debounce(n)Only fire when no value is emitted and n ms have passed
delay(n)Delay emitting of each value by n ms
distinct()Only emit next value if the value has never been seen before
filter(x => x > 0)Only forward elements when fn is truthy
flatMap(x => Observable.of(x + 1, x +2))Combine all values in the order they arrive
map(...fns)map(x => x + 1)Apply a function to transform a value
scan((acc, x) => acc + x)Same as Array.reduce but for Observables
switchMap(x => )Combine all values, but only from the most recent Observable
take(n)Take n elements and complete the chain
throttle(n)Drop values until n ms have passed

FAQ

Q: Why a new library, why not contribute to RxJS?

This library started is more of a learning experience. For me I find it easiest to learn new concepts by implementing them myself.

If this experiment is successful and the improvements are good enough, I'll be happy to contribute to rxjs. Right now the improvements made here are minor and will likely not affect most real-world apps.

Q: What makes fast-observables faster than other libraries?

The main performance benefit of fast-observables is a more performant base Observable class. When creating a new Observable instance, all libraries basically follow these steps:

  1. instantiate Observable
  2. instantiate Subscription
  3. instantiate SubscriptionObserver and attach to Subscription
  4. attach Subscription to Observable

This library doesn't need step 3, meaning we save one function call with each Observable.

The other reason is that fast-observables is simply smaller than rxjs. This leads to quicker boot up times and slightly faster operators.

Credits

This library wouldn't be possible without the amazing work of the rx-community and its contributors. Their code did help me a lot when figuring out the interaction between observables, subscribers and how to implement asynchronous scheduling.

License

MIT, see License file.

0.3.0

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.2

6 years ago

0.0.1

6 years ago