Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/pedromsilvapt/data-async-iterator
Batteries-included utility functions to work with async iterables as available in ES2018/TypeScript
https://github.com/pedromsilvapt/data-async-iterator
async es2018 generators iterables iterators nodejs typescript
Last synced: 11 days ago
JSON representation
Batteries-included utility functions to work with async iterables as available in ES2018/TypeScript
- Host: GitHub
- URL: https://github.com/pedromsilvapt/data-async-iterator
- Owner: pedromsilvapt
- Created: 2018-06-01T17:57:07.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2022-04-24T20:35:35.000Z (over 2 years ago)
- Last Synced: 2024-12-09T00:54:42.806Z (about 1 month ago)
- Topics: async, es2018, generators, iterables, iterators, nodejs, typescript
- Language: TypeScript
- Homepage:
- Size: 109 KB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Async Iterator
> Batteries-included utility functions to work with async iterables as available in ES2018/TypeScript
# Installation
```shell
npm install --save data-async-iterators
```# Tips & Tricks
- Iterators as lazy/pull-based
- They only calculate the next value when it is requested; thus only calculating the values that are needed
- Some methods require buffering values: be careful when mixing them with slow consumers
- Iterators need consumers: since transformations are lazy, not consuming (subscribing) to an iterator means nothing happens
- When manually using an iterator (calling `next()`), one should be careful to call `return()` on iterators that provide it as well, when the iterator is not needed anymore before it has ended, to allow it to free any resources it might be holding
- Most operators return iterables. If provided with iterables as well, they can be iterated multiple times (instead of just once). Other iterators return iterators: these can only be iterated once
- Most operators in this library accept `AsyncIterableLike` instead of `AsyncIterable`. This means certain rules apply:
- `Iterable`'s are transformed to `AsyncIterable`'s;
- `Iterator`'s and `AsyncIetrator`'s are transformed to `AsyncIterable`'s that always return the same, original iterator;
- `Promise>`'s are converted to `AsyncIterable`, waiting for the promise before using the resolved iterable;
- The operator `fromPromise( promise : Promise )` returns an `AsyncIterable` that only ever emits one value or one exception, whatever is resolved by the promise;# Usage
Contains all the common utility functions like map, filter, takeWhile, flatMap, concat, and many more as well as more async-centric ones
like flatMapConcurrent, debounce, throttle, buffered, etc...```typescript
import { from, delay, map, flatMapConcurrent } from 'data-async-iterators';// Create an asynchonous iterable stream
const source = delay( from( [ 1, 2, 3, 4 ] ), 1000 );// A closure that takes a number and slowly returns the number and it's square
const mapper = number => delay( from( [ number, number * number ] ), 4000 );// Run mapper concurrently only twice
const flatMapConcurrent( source, mapper, 2 );// And finally consume the values (returns a promise notifying when the iterator ends)
forEach( source, res => console.log( res ) );
```Or maybe a more pratical example
```typescript
import { merge, map, forEach } from 'data-async-iterators';function findDevices () : AsyncIterable { /* ... */ };
function connectDevice ( device : Device ) : AsyncIterable { /* ... */ };
function processStatus ( status : DeviceStatus ) : Promise { /* ... */ };
// Gets an async iterable of devices found
const devices : AsyncIterable = findDevices();// For each iterable calls the connectDevice that returns an iterable documenting the statuses changes of each device
const statuses : AsyncIterable = merge( map( devices, connectDevice ) );// Consumes all
forEach( statuses, processStatus );
```Sometimes chaining functions in this way is not very readable, and therefore this package provides a utility class called `AsyncStream` that is a simple wraper around an iterable with all the operators as methods.
```typescript
import { AsyncStream } from 'data-async-iterators';const stream = AsyncStream.range( 1, 10 )
// Delay each number by 100 milliseconds
.delay( 100 )
// Double each number
.map( v => v * 2 )
// For each n number, generate n repetitions
.flatMap( v => AsyncStream.repeat( v, v ) )
// Ignore the first and last ten numbers
.slice( 10, -10 );// Since AsyncStream is a regular iterable, we can
for await ( let number of stream ) {
console.log( number );
}// Or
stream.forEach( number => console.log( number ) );// To convert any regular AsyncIterable (or promises, regular iterables, arrays, etc...)
// into an AsyncStream just do:
const stream = new AsyncStream( iterable );
```