|
| 1 | +--- |
| 2 | +id: overview |
| 3 | +--- |
| 4 | + |
| 5 | +# Overview |
| 6 | + |
| 7 | +## Introduction |
| 8 | + |
| 9 | +FxTS is a library for functional programming using iterable/asyncIterable. |
| 10 | +It provides users to write more declarative code, as well as to handle asynchronous data and functions. |
| 11 | + |
| 12 | +to build the above, we have many features such as: |
| 13 | + |
| 14 | +- Lazy evaluation |
| 15 | + - It is a useful way to represent large or possibly infinite enumerable data. |
| 16 | +- Handling concurrent requests |
| 17 | + - It can handle multiple asynchronous requests and also control the count of requests. |
| 18 | +- Type inference |
| 19 | + - Function composition can be inferred. |
| 20 | +- Follow [iteration protocal](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols) Iterable / AsyncIterable |
| 21 | + - FxTS follows the protocol of the language standard. |
| 22 | + This means that it matches well with existing functions and functions that will be added in the future. |
| 23 | + |
| 24 | +## Examples |
| 25 | + |
| 26 | +### Normal |
| 27 | + |
| 28 | +We provide [lazy evaluation](https://en.wikipedia.org/wiki/Lazy_evaluation). |
| 29 | + |
| 30 | +```ts |
| 31 | +import { pipe, peek, range, map, filter, take, toArray } from "@fxts"; |
| 32 | + |
| 33 | +pipe( |
| 34 | + range(100), |
| 35 | + peek((a) => console.log(a)), // log 4 times (1,2,3,4) |
| 36 | + map((a) => a + 10), |
| 37 | + filter((a) => a % 2 === 0), |
| 38 | + take(2), |
| 39 | + toArray, |
| 40 | +); |
| 41 | +``` |
| 42 | + |
| 43 | +Even if you do `filter` after `map`, it doesn't matter. 2 items are extracted, (only 4 items are evaluated 1,2,3,4). Lazy functions can be found [here](https://fxts.dev/docs/index#lazy) |
| 44 | + |
| 45 | +### Function composition |
| 46 | + |
| 47 | +Combinations of `Lazy` functions don't evaluate actual values like [generator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator). |
| 48 | +It can be evaluate with a Strict(`toArray`) or [for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of), [await for-of](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for-await...of). Strict functions can be found [here](https://fxts.dev/docs/index#strict) |
| 49 | + |
| 50 | +```ts |
| 51 | +import { pipe, range, map, filter, take, toArray } from "@fxts"; |
| 52 | + |
| 53 | +const nums = pipe( |
| 54 | + range(Infinity), |
| 55 | + map((a) => a * a), |
| 56 | + take(3), |
| 57 | +); // not evaluated not yet |
| 58 | + |
| 59 | +const result = pipe( |
| 60 | + nums, |
| 61 | + filter((a) => a % 2 === 0), |
| 62 | + toArray, // Strict function |
| 63 | +); |
| 64 | +``` |
| 65 | + |
| 66 | +### Handling asynchronous data |
| 67 | + |
| 68 | +When dealing with asynchronous values |
| 69 | + |
| 70 | +```ts |
| 71 | +import { pipe, peek, range, map, filter, take, toArray } from "@fxts"; |
| 72 | + |
| 73 | +await pipe( |
| 74 | + Promise.resolve([1, 2, 3, 4]), |
| 75 | + map((a) => a + 10), |
| 76 | + map(async (a) => a + 10), // also possible |
| 77 | + filter((a) => a % 2 === 0), |
| 78 | + take(2), |
| 79 | + toArray, |
| 80 | +); |
| 81 | +``` |
| 82 | + |
| 83 | +When asynchronous values are contained in an array |
| 84 | + |
| 85 | +```ts |
| 86 | +import { pipe, toAsync, peek, range, map, filter, take, toArray } from "@fxts"; |
| 87 | + |
| 88 | +await pipe( |
| 89 | + toAsync([ |
| 90 | + Promise.resolve(1), |
| 91 | + Promise.resolve(2), |
| 92 | + Promise.resolve(3), |
| 93 | + Promise.resolve(4), |
| 94 | + ]), |
| 95 | + map((a) => a + 10), |
| 96 | + filter((a) => a % 2 === 0), |
| 97 | + take(2), |
| 98 | +); |
| 99 | +``` |
| 100 | + |
| 101 | +### Concurrent |
| 102 | + |
| 103 | +It handles multiple asynchronous requests and also controls the count of requests |
| 104 | + |
| 105 | +```ts |
| 106 | +import { pipe, toAsync, delay, peek, range, map, filter, take } from "@fxts"; |
| 107 | + |
| 108 | +await pipe( |
| 109 | + toAsync(range(Infinity)), |
| 110 | + map((page) => delay(1000, page)), // 1,2,3,4,5,6 |
| 111 | + filter((a) => a % 2 === 0), // 2,4,6 |
| 112 | + concurrent(3), |
| 113 | + take(2), |
| 114 | + toArray, // 2 seconds |
| 115 | +); |
| 116 | +``` |
| 117 | + |
| 118 | +You can see that it takes 6 seconds when requesting one by one but takes 2 seconds when requesting using [concurrent](https://fxts.dev/docs/concurrent) |
| 119 | + |
| 120 | +A more practical code is below. |
| 121 | + |
| 122 | +<iframe src="https://codesandbox.io/embed/fxts-concurrent-useful-0frg2?fontsize=14&hidenavigation=1&theme=dark" |
| 123 | + style={{height:800, width:"100%", border:0, borderRadius:4,overflow:"hidden"}} |
| 124 | + title="fxts-concurrent-useful" |
| 125 | + allow="accelerometer; ambient-light-sensor; camera; encrypted-media; geolocation; gyroscope; hid; microphone; midi; payment; usb; vr; xr-spatial-tracking" |
| 126 | + sandbox="allow-forms allow-modals allow-popups allow-presentation allow-same-origin allow-scripts" |
| 127 | +></iframe> |
| 128 | +
|
| 129 | +### Error handle |
| 130 | + |
| 131 | +Since FxTS follows the protocol of standard, you can easily handle errors with `try-catch`. |
| 132 | + |
| 133 | +- synchronous |
| 134 | + |
| 135 | +```ts |
| 136 | +import { pipe, toAsync, toArray } from "@fxts"; |
| 137 | + |
| 138 | +try { |
| 139 | + pipe( |
| 140 | + [1, 2, 3, 4, 5], |
| 141 | + map((a) => { |
| 142 | + throw "err"; |
| 143 | + }), |
| 144 | + toArray, |
| 145 | + ); |
| 146 | +} catch (err) { |
| 147 | + // handle err |
| 148 | +} |
| 149 | +``` |
| 150 | + |
| 151 | +- asynchronous |
| 152 | + |
| 153 | +```ts |
| 154 | +import { pipe, toAsync, map, toArray } from "@fxts"; |
| 155 | + |
| 156 | +try { |
| 157 | + await pipe( |
| 158 | + [1, 2, 3, 4, 5], |
| 159 | + map(async (a) => { |
| 160 | + throw "err"; |
| 161 | + }), |
| 162 | + toArray, |
| 163 | + ); |
| 164 | +} catch (err) { |
| 165 | + // handle err |
| 166 | +} |
| 167 | +``` |
0 commit comments