asynciteration v0.1.6
asynciteration
A library of Promise-based iteration methods with great async/await support and Flow typings.
Installation
Simply do: npm install asynciteration
.
Example
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:
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 areturn
statement appears inside the body with a value other than 'undefined', the loop will break and thewhileCondition
will return the value. For instance:
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
orNamedNodeMap
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 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 thestartFrom
value is 0.
v0.01:
- First release. Has the methods
forEach
,map
,filter
andwhileCondition
Usage
Import it in your project like this:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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:
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.