Skip to main content

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]