Method Chaining
You can handle Iterable/AsyncIterable through a pipe, but fxts
also provides data change in the form of method chaining.
fx([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
.filter((a) => a % 2 === 0) // [0, 2]
.map((a) => a * a) // [0, 4]
.take(2) // [0, 4]
.reduce(sum); // 4
fx("abc")
.map((a) => a.toUpperCase()) // ["A", "B"]
.take(2)
.toArray(); // ["A", "B"]
Note: Since fx
defaults to lazy evaluation, it is not actually evaluated until strict evaluation methods such as toArray
, groupBy
, indexBy
, and some
are executed.
For details on lazy evaluation, please refer to https://fxts.dev/docs/lazy-evaluation.
Support for handling AsyncIterable
fx
can also handle AsyncIterator values. toAsync
is used in the example below to create an AsyncIterator
value.
await fx(toAsync([1, 2, 3, 4]))
.filter(async (a) => a % 2 === 0)
.map(async (a) => a * a)
.reduce(sum);
await fx([1, 2, 3, 4])
.filter((a) => a % 2 === 0)
.toAsync() // if async function returns
.map(async (a) => a * a)
.reduce(sum);
Handle Concurrency
fx
supports concurrent operation. As we saw in concurrent, concurrent can only be used in asyncIterable.
For details on handling concurrent with fxts
, please refer to https://fxts.dev/docs/handle-concurrency
/**
*
* evaluation
* ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
* │ 1 │──│ 2 │──│ 3 │──│ 4 │──│ 5 │──│ 6 │
* └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘ └──┬──┘
* map │ │ │ │ │ │
* concurrent(2) (1) (1) (2) (2) (3) (3)
* │ │ │ │ │ │
* ▼ ▼ ▼ ▼ ▼ ▼
*/
await fx(toAsync(range(1, 7)))
// async function returns
.map(async (a) => delay(100, a))
.concurrent(2)
.consume(); // It takes approximately 300ms.
Etc
fx
does not provide all the functions of fxts
as methods.
If you want to use the fxts
function which is not provided or additional functions, you can use the chain
method.
fx([1, 2, 3, 4])
.chain(append(5))
.map((a) => a + 10)
.toArray(); // [11, 12, 13, 14, 15]