Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/toniov/p-iteration
Utilities that make array iteration easy when using async/await or Promises
https://github.com/toniov/p-iteration
array array-iteration array-methods async async-await async-functions await es2017 promise
Last synced: 3 days ago
JSON representation
Utilities that make array iteration easy when using async/await or Promises
- Host: GitHub
- URL: https://github.com/toniov/p-iteration
- Owner: toniov
- Created: 2017-06-14T10:05:53.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2020-10-06T14:19:03.000Z (over 4 years ago)
- Last Synced: 2025-01-20T01:03:38.490Z (11 days ago)
- Topics: array, array-iteration, array-methods, async, async-await, async-functions, await, es2017, promise
- Language: JavaScript
- Homepage: https://toniov.github.io/p-iteration
- Size: 707 KB
- Stars: 352
- Watchers: 10
- Forks: 19
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# p-iteration [![Build Status](https://travis-ci.org/toniov/p-iteration.svg?branch=master)](https://travis-ci.org/toniov/p-iteration) [![NPM version](https://badge.fury.io/js/p-iteration.svg)](http://badge.fury.io/js/p-iteration)
> Make array iteration easy when using async/await and promises
- Same functionality as the ES5 Array iteration methods we all know
- All the methods return a `Promise`, making them awaitable and thenable
- Allow the usage of async functions as callback
- Callbacks run concurrently
- Lightweight (no prd dependencies)## Install
```
$ npm install --save p-iteration
```## Usage
Smooth asynchronous iteration using `async/await`:
```js
const { map } = require('p-iteration');// map passing an async function as callback
function getUsers (userIds) {
return map(userIds, async userId => {
const response = await fetch(`/api/users/${userId}`);
return response.json();
});
}// map passing a non-async function as callback
async function getRawResponses (userIds) {
const responses = await map(userIds, userId => fetch(`/api/users/${userId}`));
// ... do some stuff
return responses;
}// ...
``````js
const { filter } = require('p-iteration');async function getFilteredUsers (userIds, name) {
const filteredUsers = await filter(userIds, async userId => {
const response = await fetch(`/api/users/${userId}`);
const user = await response.json();
return user.name === name;
});
// ... do some stuff
return filteredUsers;
}// ...
```All methods return a Promise so they can just be used outside an async function just with plain Promises:
```js
const { map } = require('p-iteration');map([123, 125, 156], (userId) => fetch(`/api/users/${userId}`))
.then((result) => {
// ...
})
.catch((error) => {
// ...
});
```If there is a Promise in the array, it will be unwrapped before calling the callback:
```js
const { forEach } = require('p-iteration');
const fetchJSON = require('nonexistent-module');function logUsers () {
const users = [
fetchJSON('/api/users/125'), // returns a Promise
{ userId: 123, name: 'Jolyne', age: 19 },
{ userId: 156, name: 'Caesar', age: 20 }
];
return forEach(users, (user) => {
console.log(user);
});
}
``````js
const { find } = require('p-iteration');
const fetchJSON = require('nonexistent-module');function findUser (name) {
const users = [
fetchJSON('/api/users/125'), // returns a Promise
{ userId: 123, name: 'Jolyne', age: 19 },
{ userId: 156, name: 'Caesar', age: 20 }
];
return find(users, (user) => user.name === name);
}
```The callback will be invoked as soon as the Promise is unwrapped:
```js
const { forEach } = require('p-iteration');// function that returns a Promise resolved after 'ms' passed
const delay = (ms) => new Promise(resolve => setTimeout(() => resolve(ms), ms));// 100, 200, 300 and 500 will be logged in this order
async function logNumbers () {
const numbers = [
delay(500),
delay(200),
delay(300),
100
];
await forEach(numbers, (number) => {
console.log(number);
});
}
```## API
The methods are implementations of the ES5 Array iteration methods we all know with the same syntax, but all return a `Promise`. Also, with the exception of `reduce()`, all methods callbacks are run concurrently. There is a series version of each method, called: `${methodName}Series`, series methods use the same API that their respective concurrent ones.
There is a link to the [original reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array) of each method in the docs of this module:
- [`forEach`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#forEach)
- [`forEachSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#forEachSeries)
- [`map`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#map)
- [`mapSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#mapSeries)
- [`find`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#find)
- [`findSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#findSeries)
- [`findIndex`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#findIndex)
- [`findIndexSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#findIndexSeries)
- [`some`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#some)
- [`someSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#someSeries)
- [`every`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#every)
- [`everySeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#everySeries)
- [`filter`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#filter)
- [`filterSeries`(array, callback, [thisArg])](https://toniov.github.io/p-iteration/global.html#filterSeries)
- [`reduce`(array, callback, [initialValue])](https://toniov.github.io/p-iteration/global.html#reduce)
## Instance methods
Extending native objects is discouraged and I don't recommend it, but in case you know what you are doing, you can extend `Array.prototype` to use the above methods as instance methods. They have been renamed as `async${MethodName}`, so the original ones are not overwritten.
```js
const { instanceMethods } = require('p-iteration');Object.assign(Array.prototype, instanceMethods);
async function example () {
const foo = await [1, 2, 3].asyncMap((id) => fetch(`/api/example/${id}`));
}
```## License
MIT © [Antonio V](https://github.com/toniov)