rx-queue
Version:
Easy to Use ReactiveX Queue that Supports Delay/DelayExecutor/Throttle/Debounce/Concurrency Features Powered by RxJS/IxJS
55 lines (45 loc) • 1.49 kB
text/typescript
/**
* If you know how iterators work and how they are consumed you would't need any extra library,
* since it can become very easy to build your own concurrency yourself.
* — @Endless
*
* Inspired by: @link https://stackoverflow.com/a/51020535/1123955
*/
/**
* Huan's stackoverflow answer (code example) for `merge`:
* @link https://stackoverflow.com/a/69985103/1123955
*/
import {
merge,
} from 'ix/asynciterable/index.js'
type ExecuterTask <S, T> = (value: S) => T | Promise<T>
const executeTask = <S, T> (task: ExecuterTask<S, T>) => async function * (
iterator: IterableIterator<S>,
): AsyncIterableIterator<T> {
for (const one of iterator) {
const result = await task(one)
yield result
}
}
/**
* Execute task with the concurrency on an iterator
* The order will not be guaranteed. (mostly will be different)
*/
const concurrencyExecuter = (concurrency = 1) => <S, T>
(task : ExecuterTask<S, T>) =>
async function * (
iterator: Array<S> | IterableIterator<S>,
): AsyncIterableIterator<T> {
if (Array.isArray(iterator)) {
iterator = iterator.values()
}
const executer = executeTask(task)
const resultIteratorList = new Array(concurrency)
.fill(iterator)
.map(executer) as [AsyncIterableIterator<T>, ... AsyncIterableIterator<T>[]]
yield * merge(...resultIteratorList)
}
export {
concurrencyExecuter,
}