# asynciteration

> A collection of methods for handling asynchronous work on collections

Latest version **0.1.6** (published 2016-09-30) · ISC license · 0 weekly downloads

> **Deprecated.** This package is deprecated.

## Install

```sh
npm install asynciteration
pnpm add asynciteration
yarn add asynciteration
bun add asynciteration
```

## Health

**Score 10/100 (F)** — status: deprecated.

Negative: deprecated.

## Facts

| | |
|---|---|
| Version | 0.1.6 |
| Published | 2016-09-30 |
| First published | 2016-08-13 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 1 |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Frederik Wessberg |
| Maintainers | wessberg |
| Keywords | async, await, promise, iteration, collection, map, forEach, filter, while |

## Links

- npm: https://www.npmjs.com/package/asynciteration
- npm.io page: https://npm.io/package/asynciteration

## Dependencies (1)

- [typedetection](https://npm.io/package/typedetection.md) >=0.0.2

## Alternatives

- [@commercetools/sync-actions](https://npm.io/package/@commercetools/sync-actions.md) — 25.1K weekly downloads
- [cwait](https://npm.io/package/cwait.md) — 21.4K weekly downloads
- [@ledgerhq/hw-app-cosmos](https://npm.io/package/@ledgerhq/hw-app-cosmos.md) — 4.2K weekly downloads
- [@financial-times/o-loading](https://npm.io/package/@financial-times/o-loading.md) — 2.8K weekly downloads
- [fa](https://npm.io/package/fa.md) — 185 weekly downloads

## Recent versions

- 0.1.6 (latest) — 2016-09-30
- 0.1.5 — 2016-09-09
- 0.1.4 — 2016-09-04
- 0.1.3 — 2016-09-04
- 0.1.2 — 2016-08-25
- 0.1.1 — 2016-08-24
- 0.1.0 — 2016-08-23
- 0.0.9 — 2016-08-15
- 0.0.8 — 2016-08-15
- 0.0.7 — 2016-08-14
- 0.0.6 — 2016-08-14
- 0.0.5 — 2016-08-14
- 0.0.4 — 2016-08-14
- 0.0.3 — 2016-08-14
- 0.0.2 — 2016-08-13
- … 1 more at https://npm.io/package/asynciteration/versions

## README

# asynciteration [![NPM version][npm-image]][npm-url]
> A library of Promise-based iteration methods with great async/await support and Flow typings.

## Installation
Simply do: `npm install asynciteration`.

## Example

```javascript
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

await forEach(arr, async function (item, index, collection) {
	await someAsyncStuff(item);
	await someOtherAsyncStuff(item, index, collection);
});
// Continues execution from here when all items has been iterated through.
```

Or the same with Promises:
```javascript
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

forEach(arr, (item, index) => {
	return new Promise(resolve => {
		someAsyncStuff(item).then(resolve);
		someOtherAsyncStuff(item, index).then(resolve);
	});
}).then(() => {
	// Continues execution from here when all items has been iterated through.
});
```

## Changelog:

**v0.16**:

- Fixed a few typing errors.

**v0.15**:

- New behavior for `whileCondition()`. If a `return` statement appears inside the body with a value other than 'undefined', the loop will break and the `whileCondition` will return the value.
For instance:
```javascript
let isAwesome = await whileCondition(() => true, async () => {
	 await awesomeStuff();
	if (somethingHasChangedNow) return true;
});
// isAwesome will be 'true' if 'somethingHasChangedNow' is true.
```
This makes it possible to use the return statement like a `break` statement in a traditional `while`-loop.

**v0.14**:

- Fixed documentation. Added a new method: `forRange()`.

**v0.13**:

- Made Promise-checks more strict to comply with Flow v0.32.

**v0.12**:

- Fixed a typing error.

**v0.11**:

- Updated package dependencies and keywords.

**v0.10**:

- Rebuilt without lodash for smaller footprint.
- Added new flexible versions:
	- `asynciteration.js`: The standard version, transpiled to ES5 and with inlined dependencies.
	- `external.js`: Transpiled to ES5 but with external dependencies for code sharing.
	- `native.js` - ES-modules and inlined dependencies.
	- `native-external.js` - ES-modules and external dependencies for code-sharing.
	- `typed.js` - ES-modules, flow typings and external dependencies for code-sharing.

**v0.09**:
- Fixed a bug with iterating through `HTMLCollection` or `NamedNodeMap` collections.

**v0.08**:
- Now works for `string` objects and array-like objects.
- Fixed a few tests.

**v0.07**:
- Fixed typing errors.

**v0.06**:
- Rewritten with Generics. Stricter but more precise declarations of `handler` arguments.

**v0.04**:
- Rewritten with optional [Flow](https://flowtype.org/) typings. To use it, import from `"asynciteration/typed"` instead. Note that you will need to compile flow typings down to readable Javascript using Babel or something similar.
- Wrote tests for empty collections.
- Empty collections will now properly resolve promises.

**v0.02**:
- Empty collections shouldn't throw `RangeError` exceptions when the `startFrom` value is 0.

**v0.01**:
- First release. Has the methods `forEach`, `map`, `filter` and `whileCondition`

## Usage
Import it in your project like this:

```javascript
import {forEach, ...} from "asynciteration" // (standard) Transpiled to ES5, inlined dependencies.;
// or

import {forEach, ...} from "asynciteration/external" // Transpiled to ES5, external dependencies.
// or

import {forEach, ...} from "asynciteration/native" // Transpiled to ES5, native ES-modules, inlined dependencies.
// or

import {forEach, ...} from "asynciteration/native-external" // Transpiled to ES5, native ES-modules external dependencies.
// or

import {forEach, ...} from "asynciteration/typed" // Flow typings, ES-modules, external dependencies.
```

The iterators are all based on Promises which means that they work well with `async/await` too.

They follow the `forEach` conventions for `Array` and `Map` instances.

All methods are strict and will fail hard with relevant errors if the input data isn't valid.

## Documentation

#### Types:

```javascript
Collection<T>:  Array<T>|Map<any,T>|{length: number}|string;

VoidHandler<T>: (item: T, key?: any, collection?: Collection<T>) => Promise<void>|void;

ValueHandler<T>: (item?: T, key?: any, collection?: Collection<T>) => Promise<?any>|?any;

BooleanHandler<T>: (item?: T, key?: any, collection?: Collection<T>) => Promise<boolean>|boolean;

EmptyHandler: () => Promise<void>|void;

Handler<T> = EmptyHandler | VoidHandler<T> | ValueHandler<T> | BooleanHandler<T>;

interface Normalized<T> = {
	size: number,
	get: (item: number) => T,
	arrayLike: Array<[any, T]>,
	collection: Collection<T>
};
```


### `#forEach()`

*An async forEach loop. Calls the provided handler with the same arguments as the collection's native 'forEach' method.*

**Signature:**

```javascript
forEach<T> (collection: Collection<T>, handler: VoidHandler<T>, startFrom: number = 0, waitForNextFrame: boolean = false): Promise<void>
```

**Arguments**:

- `collection: Collection<T>` - The collection to iterate over.

- `handler: VoidHandler<T>` - The function to invoke for each iteration. Follows defaults argument positions for 'forEach' methods on arrays and maps.

- `startFrom: number = 0` - Optionally, the index to start from. Useful if you want to "skip" the tail of the collection.

- `waitForNextFrame: boolean = false` - Optionally, if each iteration call should be pushed to the end of the current execution queue.

**Returns**:

`Promise<void>`

#### Example 1 - with an array:
```javascript

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

await forEach(arr, async function (item, index, collection) {
	await someAsyncStuff(item);
	await someOtherAsyncStuff(item, index, collection);
});
// Continues execution from here when all items has been iterated through.
```

#### Example 2 - with a Map:
```javascript

const map = new Map([
	["a", 1],
	["b", 2]
]);

await forEach(map, async function (value, key, collection) {
	await someAsyncStuff(value);
	await someOtherAsyncStuff(key, value, collection);
});
// Continues execution from here when all items has been iterated through.
```

### `#forRange()`

*An async range. Will iterate for as many times as given in the argument 'range'.*

**Signature:**

```javascript
forRange (range: number, handler: VoidHandler, waitForNextFrame: boolean = false): Promise<void>
```

**Arguments**:

- `range: number` - The amount of times to iterate.

- `handler: VoidHandler<T>` - The function to invoke for each iteration. Is invoked with arguments: (index: number, range: number).

- `waitForNextFrame: boolean = false` - Optionally, if each iteration call should be pushed to the end of the current execution queue.

**Returns**:

`Promise<void>`

#### Example:
```javascript

const range = 10;

await forRange(range, async function (index, range) {
	await someAsyncStuff(index);
	await someOtherAsyncStuff(item, range);
});
// Continues execution from here when all numbers in the range has been iterated through.
```

### `#map()`

*An async map function. Generates a new array of all the values that is returned by the handler.*

**Signature:**

```javascript
map<T> (collection: Collection<T>, handler: ValueHandler<T>, startFrom: number = 0, waitForNextFrame: boolean = false): Promise<any[]>
```

**Arguments**:

- `collection: Collection<T>` - The collection to iterate over.

- `handler: ValueHandler<T>` - The function to invoke for each iteration. Follows defaults argument positions for 'forEach' methods on arrays and maps. Returns either a Promise that will resolve with the mapped value or the mapped value itself.

- `startFrom: number = 0` - Optionally, the index to start from. Useful if you want to "skip" the tail of the collection.

- `waitForNextFrame: boolean = false` - Optionally, if each iteration call should be pushed to the end of the current execution queue.

**Returns**:

`Promise<any[]>` - The mapped array.

#### Example 1 - with an array:
```javascript

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const mappedArr = await map(arr, async function (item) {
	await someAsyncStuff(item);
	return item * 2;
});

console.log(mappedArr); // [2, 4, 6, 8, 10, 12, 14, 16, 18, 20];
```

#### Example 2 - with a Map:
```javascript

const mapCollection = new Map([
	["a", 1],
	["b", 2]
]);

const mappedArr = await map(mapCollection, async function (value, key) {
	await someAsyncStuff(value);
	return value * 2;
});

console.log(mappedArr); // [2, 4];
```

### `#filter()`

*An async filter function. Generates a new array of all the values that the handler returns truthy values for.*

**Signature:**

```javascript
filter<T> (collection: Collection<T>, handler: BooleanHandler<T>, startFrom: number = 0, waitForNextFrame: boolean = false): Promise<T[]>
```

**Arguments**:

- `collection: collection: Collection<T>` - The collection to iterate over.

- `handler: BooleanHandler<T>` - The function to invoke for each iteration. Follows defaults argument positions for 'forEach' methods on arrays and maps. Returns either a Promise that will resolve with a boolean value or a boolean.

- `startFrom: number = 0` - Optionally, the index to start from. Useful if you want to "skip" the tail of the collection.

- `waitForNextFrame: boolean = false` - Optionally, if each iteration call should be pushed to the end of the current execution queue.

**Returns**:

`Promise<T[]>` - The filtered array.

#### Example 1 - with an array:
```javascript

const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const filteredArr = await filter(arr, async function (item) {
	await someAsyncStuff(item);
	return item % 2 === 0;
});

console.log(mappedArr); // [2, 4, 6, 8, 10];
```

#### Example 2 - with a Map:
```javascript

const map = new Map([
	["a", 1],
	["b", 2]
]);

const mappedArr = await filter(map, async function (value, key) {
	await someAsyncStuff(value);
	return value % 2 === 0;
});

console.log(mappedArr); // [2];
```

### `#whileCondition()`

*Calls the provided handler for as long as the given condition function returns a truthy value.*

**Signature:**

```javascript
whileCondition (conditionMethod: () => boolean, handler: EmptyHandler): Promise<void>
```

**Arguments**:

- `conditionMethod: () => boolean` - A function that returns a boolean. As long as it is truthy, the handler will be called infinitely.

- `handler: EmptyHandler` - The function to invoke as long as the condition returns a truthy value.

**Returns**:

`Promise<?any>` - A promise that will resolve with 'undefined' or the a value if a 'return' statement happens inside the body with a value other than 'undefined'.

#### Example:
```javascript

let result = 0;

await whileCondition(() => result <= 10, async function () {
	await someAsyncStuff();
	result++;
});

// Comes here after 10 iterations.
```

#### Example 2:
If a `return` statement appears inside the body with a value other than 'undefined', the loop will break and the `whileCondition` will return the value.
For instance:
```javascript
let isAwesome = await whileCondition(() => true, async () => {
	 await awesomeStuff();
	if (somethingHasChangedNow) return true;
});
// isAwesome will be 'true' if 'somethingHasChangedNow' is true.
```
This makes it possible to use the return statement like a `break` statement in a traditional `while`-loop.

[npm-url]: https://npmjs.org/package/asynciteration
[npm-image]: https://badge.fury.io/js/asynciteration.svg

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