# rx-queue

> Easy to Use ReactiveX Queue that Supports Delay/DelayExecutor/Throttle/Debounce/Concurrency Features Powered by RxJS/IxJS

Latest version **1.0.5** (published 2022-03-24) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install rx-queue
pnpm add rx-queue
yarn add rx-queue
bun add rx-queue
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.5 |
| Published | 2022-03-24 |
| First published | 2017-10-30 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM |
| Node | >=16 |
| Dependencies | 2 |
| Unpacked size | 136.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 76 |
| Author | Huan LI |
| Maintainers | zixia |
| Keywords | queue, delay, executor, throttle, debounce, rxjs, rx, fifo |

## Links

- npm: https://www.npmjs.com/package/rx-queue
- Repository: https://github.com/huan/rx-queue
- Homepage: https://github.com/huan/rx-queue#readme
- Issues: https://github.com/huan/rx-queue/issues
- npm.io page: https://npm.io/package/rx-queue

## Dependencies (2)

- [ix](https://npm.io/package/ix.md) ^4.5.2
- [rxjs](https://npm.io/package/rxjs.md) ^7.5.5

## Alternatives

- [cron](https://npm.io/package/cron.md) — 4.9M weekly downloads
- [@vercel/queue](https://npm.io/package/@vercel/queue.md) — 731.6K weekly downloads
- [create-sonicjs](https://npm.io/package/create-sonicjs.md) — 1.6K weekly downloads
- [@exellix/jobs-api](https://npm.io/package/@exellix/jobs-api.md) — 941 weekly downloads
- [@forwardimpact/libskill](https://npm.io/package/@forwardimpact/libskill.md) — 575 weekly downloads

## Recent versions

- 1.0.5 (latest) — 2022-03-24
- 0.9.3 (next) — 2019-07-08
- 1.0.4 — 2021-11-23
- 1.0.3 — 2021-11-23
- 0.12.6 — 2021-08-18
- 0.12.5 — 2021-08-18
- 0.12.4 — 2021-06-03
- 0.12.3 — 2021-05-29
- 0.12.2 — 2021-05-29
- 0.9.1 — 2019-06-23
- 0.8.5 — 2019-06-22
- 0.8.4 — 2019-06-22
- 0.8.2 — 2019-06-02
- 0.8.1 — 2019-03-29
- 0.6.2 — 2018-11-27
- … 57 more at https://npm.io/package/rx-queue/versions

## README

# RX-QUEUE

[![NPM](https://github.com/huan/rx-queue/actions/workflows/npm.yml/badge.svg)](https://github.com/huan/rx-queue/actions/workflows/npm.yml)
[![Windows Build status](https://img.shields.io/appveyor/ci/zixia/rx-queue/master.svg?label=Windows)](https://ci.appveyor.com/project/zixia/rx-queue)
[![NPM Version](https://badge.fury.io/js/rx-queue.svg)](https://badge.fury.io/js/rx-queue)
[![Downloads](http://img.shields.io/npm/dm/rx-queue.svg?style=flat-square)](https://npmjs.org/package/rx-queue)
[![Powered by TypeScript](https://img.shields.io/badge/Powered%20By-TypeScript-blue.svg)](https://www.typescriptlang.org/)

Easy to Use ReactiveX Queue that Supports Delay/DelayExecutor/Throttle/Debounce Features Powered by RxJS.

![RxQueue](https://huan.github.io/rx-queue/images/queue.png)
> Picture Credit: [Queues in JavaScript](https://www.kirupa.com/html5/queues_in_javascript.htm)

## API

### Class

1. [RxQueue](#rxqueue)
1. [DelayQueue](#delayqueue)
1. [ThrottleQueue](#throttlequeue)
1. [DebounceQueue](#debouncequeue)
1. [DelayQueueExecutor](#DelayQueueExecutor)

### Function

1. [concurrencyExecuter()](#concurrencyexecuter)

### RxQueue

`RxQueue` is the base class of all other queues. It extends from RxJS Subject.

**Example:**

```ts
import { RxQueue } from 'rx-queue'

const queue = new RxQueue()
queue.next(1)
queue.next(2)
queue.next(3)

queue.subscribe(console.log)
// Output: 1
// Output: 2
// Output: 3
```

### DelayQueue

`DelayQueue` passes all the items and add delays between items.

![DelayQueue](https://huan.github.io/rx-queue/images/delay.png)
> Picture Credit: [ReactiveX Single Operator Delay](http://reactivex.io/documentation/single.html)

Practical examples of `DelayQueue`:

1. We are calling a HTTP API which can only be called no more than ten times per second, or it will throw a `500` error.

**Example:**

```ts
import { DelayQueue } from 'rx-queue'

const delay = new DelayQueue(500)  // set delay period time to 500 milliseconds
delay.subscribe(console.log)

delay.next(1)
delay.next(2)
delay.next(3)

// Output: 1
// Paused 500 millisecond...
// Output: 2
// Paused 500 millisecond...
// Output: 3
```

### ThrottleQueue

`ThrottleQueue` passes one item and then drop all the following items in a period of time.

![ThrottleQueue](https://huan.github.io/rx-queue/images/throttle.png)
> Picture Credit: [ReactiveX Observable Throttle](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-throttle)

By using throttle, we don't allow to our queue to pass more than once every X milliseconds.

Practical examples of `ThrottleQueue`:

1. User is typing text in a textarea. We want to call auto-save function when user is typing, and want it only run at most once every five minutes.

**Example:**

```ts
import { ThrottleQueue } from 'rx-queue'

const throttle = new ThrottleQueue(500)  // set period time to 500 milliseconds
throttle.subscribe(console.log)

throttle.next(1)
throttle.next(2)
throttle.next(3)

// Output: 1
```

### DebounceQueue

`DebounceQueue` drops a item if there's another one comes in a period of time.

![DebounceQueue](https://huan.github.io/rx-queue/images/debounce.png)
> Picture Credit: [ReactiveX Observable Debounce](http://reactivex.io/documentation/operators/debounce.html)

The Debounce technique allow us to deal with multiple sequential items in a time period to only keep the last one.

Debouncing enforces that no more items will be passed again until a certain amount of time has passed without any new items coming.

Practical examples of `DebounceQueue`:

1. User is typing text in a search box. We want to make an auto-complete function call only after the user stop typing for 500 milliseconds.

**Example:**

```ts
import { DebounceQueue } from 'rx-queue'

const debounce = new DebounceQueue(500)  // set period time to 500 milliseconds
debounce.subscribe(console.log)

debounce.next(1)
debounce.next(2)
debounce.next(3)

// Paused 500 millisecond...
// Output: 3
```

### DelayQueueExecutor

`DelayQueueExecutor` calls functions one by one with a delay time period between calls.

> If you want this feature but do not want rxjs dependencies, you can have a look on a zero dependencies alternative: [BottleNeck](https://github.com/SGrondin/bottleneck）

![DelayQueueExecutor](https://huan.github.io/rx-queue/images/delay.png)
> Picture Credit: [ReactiveX Single Operator Delay](http://reactivex.io/documentation/single.html)

Practical examples of `DelayQueueExecutor`:

1. We are calling a HTTP API which can only be called no more than ten times per second, or it will throw a `500` error.

**Example:**

```ts
import { DelayQueueExecutor } from 'rx-queue'

const delay = new DelayQueueExecutor(500)  // set delay period time to 500 milliseconds

delay.execute(() => console.log(1))
delay.execute(() => console.log(2))
delay.execute(() => console.log(3))

// Output: 1
// Paused 500 millisecond...
// Output: 2
// Paused 500 millisecond...
// Output: 3
```

### `concurrencyExecuter()`

When we have a array and need to use an async function to get the result of them, we can use `Promise.all()`:

```ts
const asyncTask = async function (item) {
  /**
   * Some heavy task, like:
   *  1. requires XXX MB of memory
   *  2. make 10+ new network connections and each takes 10+ seconds
   *  3. etc.
   */
}

const result = await Promise.all(
  hugeArray.map(item => asyncTask),
)
```

Because the above example `asyncTask` requires lots of resource for each task,
so if the `hugeArray` has many items, like 1,000+,
then to use the `Promise.all` will very likely to crash the system.

The solution is that we can use `concurrencyExecuter()` to execute them in parallel with a concurrency limitation.

```ts
// async task:
const heavyTask = (n: number) => Promise.resolve(resolve => setTimeout(resolve(n^2), 100))

const results = concurrencyExecuter(
  2,          // concurrency
)(
  heavyTask,  // task async function
)(
  [1, 2, 3],  // task arguments
)

/**
 * in the following `for` loop, we will have 2 currency tasks running at the same time.
 */
for await (const result of results) {
  console.log(result)
}
```

That's it.

## SEE ALSO

* [Writing Marble Tests](https://github.com/ReactiveX/rxjs/blob/master/doc/writing-marble-tests.md)

## CHANGELOG

### main v1.0 (Nov 23, 2021)

1. ES Module Support
1. TypeScript 4.5
1. `concurrencyExecuter()` method added

### v0.12 - May 2021

1. Upgrade RxJS to v7.1
1. Upgrade TypeScript to v4.3
1. Fix RxJS breaking changes [#71](https://github.com/huan/rx-queue/issues/71)

### v0.8 - Mar 2019

1. Fix typo: issue [#40](https://github.com/huan/rx-queue/issues/40) - rename `DelayQueueExector` to `DelayQueueExecutor`

### v0.6 - Sep 2018

1. fix exception bug in browser(ie. Angular)

### v0.4 - May 2018

1. Upgrade to RxJS 6
1. Moved CI from Travis-ci.org  to Travis-ci.com

### v0.2 - Oct 30, 2017

1. Support: `DelayQueue`, `ThrottleQueue`, `DebounceQueue`, `DelayQueueExecutor`.
1. first version

## AUTHOR

[Huan LI (李卓桓)](http://linkedin.com/in/zixia) \<zixia@zixia.net\>

[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)

## COPYRIGHT & LICENSE

* Code & Docs © 2017-now Huan LI \<zixia@zixia.net\>
* Code released under the Apache-2.0 License
* Docs released under Creative Commons

---
_Source: https://npm.io/package/rx-queue · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
