Prray
"Promisified" Array, it compatible with the original Array but comes with async versions of native Array methods
Install / Use
/learn @Bin-Huang/PrrayREADME
Prray -- "Promisified" Array, it compatible with the original Array but comes with async versions of native Array methods, such as mapAsync, filterAsync, everyAsync...
- compatible with normal array
- comes with async versions of native Array methods
- supports method chaining with normal and async methods
- supports concurrency limit
- it works without any prototype pollution
- zero-dependency, it can run on both browser and Node.js
- well-tested, well-documented
import Prray from 'prray'
// 1) create
const urls = Prray.from(['www.google.com', 'npmjs.org'])
// 2) async method
let responses = await urls.mapAsync(fetch)
// 3) method chaining with both normal and async methods
await urls
.concat(['github.com', 'wikipedia.org'])
.mapAsync(request)
.filter(isValidHtml)
.forEachAsync(saveToDB)
// 4) concurrency limit
responses = await urls.mapAsync(fetch, { concurrency: 10 })
Prray aims to replace the original Array in some cases for convenience 😜
- Install
- Compatibility with normal Array
- How it work?
- Distinguish between prray and normal array
- Methods
- Why not
bluebird - License
Install
npm
npm install prray --save
yarn
yarn add prray
Compatibility with normal Array
Prray is compatible with normal array. That means you can safely replace normal Array with Prray. And there are a lots of unit tests for prray to test compatibility with normal array.
import Prray from 'prray'
const arr = [1, 2, 3]
const prr = Prray.from(arr)
prr[0] // 1
prr[prr.length - 1] // 3
prr.length // 3
prr instanceof Array // true
Array.isArray(prr) // true
JSON.stringify(prr) // "[1, 2, 3]"
for (const v of prr) {
console.log(v)
}
// 1
// 2
// 3
[ ...prr ] // [1,2,3]
const iterator = prr[Symbol.iterator]()
iterator.next().value // 1
iterator.next().value // 2
iterator.next().value // 3
iterator.next().done // true
// In typescript, type Prray is compatible with type Array
function func(arr: number[]) {
return arr
}
func(new Prray(1, 2, 3))
How it work?
Class Prray inherits the original class Array and adds or overrides methods based on it. It works without any prototype pollution and global pollution.
const prr = Prray.from([1, 2, 3])
console.log(prr.mapAsync) // [Function]
const arr = [1, 2, 3]
console.log(arr.mapAsync) // [undefined]
Distinguish between prray and normal array
const prr = new Prray(1, 2, 3)
const arr = new Array(1, 2, 3)
Prray.isPrray(prr) // true
Prray.isPrray(arr) // false
prr instanceof Prray // true
arr instanceof Prray // false
Methods
Class Prray
The class Prray. You can think of it as class Array.
import Prray from 'prray'
const p1 = new Prray()
const p2 = new Prray('a', 'b')
const p3 = Prray.from([1, 2, 3, 4])
console.log(p2[0]) // 'a'
[NOTE]: Instead
new Prray(), usePrray.fromorPrray.ofif you want to create a new prray instance with items. Because the class Prray is so compatible with class Array, some "weird" behaviors that exists innew Array()can also occurs: when you callingnew Array(1), you get[ <1 empty item> ]instead of expected[ 1 ].
Static methods of Class Prray
Prray.from(arrayLike)
Compatible with Array.from but returns a Prray instance.
The Prray.from() method creates a new, shallow-copied Prray instance from an array-like or iterable object.
const prr = Prray.from([1, 2, 3, 4])
Prray.of(...args)
Compatible with Array.of but returns a Prray instance.
The Prray.of() method creates a new Prray instance from a variable number of arguments, regardless of number or type of the arguments.
const prr = Prray.of(1, 2, 3, 4)
Prray.isPrray(obj)
The Prray.isArray() method determines whether the passed value is a Prray instance.
Prray.isPrray([1, 2, 3]) // false
Prray.isPrray(new Prray(1, 2, 3)) // true
Prray.delay(ms)
The Prray.delay() method returns a promise (PrrayPromise exactly) that will be resolved after given ms milliseconds.
await Prray.delay(1000) // resolve after 1 second
const prr = Prray.from([1,2,3])
await prr
.mapAsync(action1)
.delay(500) // delay 500ms between two iterations
.forEach(action2)
Specific methods of Prray instance
- Prray.prototype.toArray()
- Prray.prototype.delay()
- Prray.prototype.mapAsync(func, options)
- Prray.prototype.filterAsync(func, options)
- Prray.prototype.reduceAsync(func, initialValue)
- Prray.prototype.reduceRightAsync(func, initialValue)
- Prray.prototype.findAsync(func)
- Prray.prototype.findIndexAsync(func)
- Prray.prototype.everyAsync(func, options)
- Prray.prototype.someAsync(func, options)
- Prray.prototype.sortAsync(func)
- Prray.prototype.forEachAsync(func, options)
Prray.prototype.toArray()
The toArray() method returns a new normal array with every element in the prray.
const prr = new Prray(1, 2, 3)
prr.toArray() // [1,2,3]
Prray.prototype.delay(ms)
The delay() method returns a promise (PrrayPromise exactly) that will be resolved with current prray instance after given ms milliseconds.
const emails = Prray.from(emailArray)
await emails
.mapAsync(registerReceiver)
.delay(1000)
.forEachAsync(send)
Prray.prototype.mapAsync(func, options)
Think of it as an async version of method map
The mapAsync() method returns a promise (PrrayPromise exactly) that resolved with a new prray with the resolved results of calling a provided async function on every element in the calling prray, or rejected immediately if any of the promises reject.
The provided async function is called on every element concurrently. You may optionally specify a concurrency limit.
func(currentValue, index, prray)- options
concurrencyNumber of concurrently pending promises returned by provided function. Default:Infinity
const urls = Prray.from(urlArray)
const jsons = await urls.mapAsync(fetch).mapAsync(res => res.json())
await jsons.mapAsync(insertToDB, { concurrency: 2 })
Prray.prototype.filterAsync(func, options)
Think of it as an async version of method filter
The filterAsync() method returns a promise (PrrayPromise exactly) that resolved with a new prray with all elements that pass the test implemented by the provided async function, or rejected immediately if any of the promises reject.
The provided async function is called on every element concurrently. You may optionally specify a concurrency limit.
func(currentValue, index, prray)- options
concurrencyNumber of concurrently pending promises returned by provided function. Default:Infinity
const files = Prray.from(fileArray)
await files.filterAsync(isExisted).mapAsync(removeFile)
await files.filterAsync(isExisted, { concurrency: 2 })
Prray.prototype.reduceAsync(func, initialValue)
Think of it as an async version of method reduce
The reduceAsync() method executes a async reducer function (that you provide) on each element of the prray, resulting in a single output value resolved by a promise (PrrayPromise exactly).
const productIds = Prray.from(idArray)
const total = await productIds.reduceAsync(async (total, id) => {
const price = await getPrice(id)
return total + price
}, 0)
Prray.prototype.reduceRightAsync(func, initialValue)
Think of it as an async version of method reduceRight
The reduceRightAsync() method applies an async function against an accumulator and each value of the prray (from right-to-left) to reduce it to a single value.
const productIds = Prray.from(idArray)
const total = await productIds.reduceRightAsync(async (total, id) => {
const price = await getPrice(id)
return total + price
}, 0)
