EN | KR
FxJS - Functional Extensions for Javascript
FxJS is a functional programming library based on ECMAScript 6. Iterable, Iterator, Generator, Promise.
Getting Started
Installation
In Modern Browsers Supporting ES6
<script src="path/fx.min.js"></script>
In Legacy ES5 Browsers
<script src="path/fx.es5.min.js"></script>
In Node.js
The functions of FxJS are written in ECMAScript Module.
Also, since each function is well separated into individual files,
Tree-Shaking is possible when a bundler like a webpack is bundling.
npm install fxjs2
import { map, filter, reduce, L, C } from "fxjs2";
We use esm to import the FxJS functions created in the ECMAScript Module into the CommonJS Module.
const { map, filter, reduce, L, C } = require("fxjs2");
Iteration protocols
You can evaluate the iterator as a function of FxJS.
function *fibonacci() {
let a = 0, b = 1;
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
const f = pipe(
fibonacci,
L.filter(n => n % 2 == 0),
L.takeWhile(n => n < 10));
const iterator = f();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
reduce((a, b) => a + b, f());
Iterable programming
Any value can be used with FxJS if it has a [Symbol.iterator]()
method.
const res = go(
[1, 2, 3, 4, 5],
filter(a => a % 2),
reduce(add));
log(res);
Lazy evaluation
You can do 'lazy evaluation' as a function of the L
namespace.
const res = go(
L.range(Infinity),
L.filter(a => a % 2),
L.take(3),
reduce(add));
log(res);
RFP style
Reactive functional programming style.
go(
L.range(Infinity),
L.map(delay(1000)),
L.map(a => a + 10),
L.take(3),
each(log));
Promise/async/await
Asynchronous control is easy.
await go(
L.interval(1000),
L.map(a => a + 30),
L.takeUntil(a => a == 33),
each(log));
const res = await go(
L.interval(1000),
L.map(a => a + 20),
L.takeWhile(a => a < 23),
L.map(tap(log)),
reduce(add));
log(res);
Concurrency
C
functions can be evaluated concurrency.
await map(getPage, range(1, 5));
const pages = await C.map(getPage, range(1, 5));
Like Clojure Reducers, you can handle concurrency.
go(
range(1, 5),
map(getPage),
filter(page => page.line > 50),
map(getWords),
flat,
countBy(identity),
log);
go(
L.range(1, 5),
L.map(getPage),
L.filter(page => page.line > 50),
L.map(getWords),
C.takeAll,
flat,
countBy(identity),
log);
go(
L.range(1, 5),
L.map(getPage),
L.filter(page => page.line > 50),
L.map(getWords),
C.takeAll(2),
flat,
countBy(identity),
log);
Error handling
You can use JavaScript standard error handling.
const b = go(
0,
a => a + 1,
a => a + 10,
a => a + 100);
console.log(b);
try {
const b = go(
0,
a => { throw { hi: 'ho' } },
a => a + 10,
a => a + 100);
console.log(b);
} catch (c) {
console.log(c);
}
You can use async/await and try/catch to handle asynchronous error handling.
const b = await go(
0,
a => Promise.resolve(a + 1),
a => a + 10,
a => a + 100);
console.log(b);
try {
const b = await go(
0,
a => Promise.resolve(a + 1),
a => Promise.reject({ hi: 'ho' }),
a => a + 100);
console.log(b);
} catch (c) {
console.log(c);
}
API
Extention Libraries
The following libraries are based on FxJS. These are libraries that can handle SQL and DOM through functional APIs, respectively.