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.from
orPrray.of
if 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
concurrency
Number 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
concurrency
Number 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)
Prray.prototype.findAsync(func)
Think of it as an async version of method find
The findAsync() method returns a promise (PrrayPromise
exactly) resolved with the first element in the prray that satisfies the provided async testing function.
const workers = Prray.from(workerArray)
const unhealthy = await workers.findAsync(checkHealth)
Prray.prototype.findIndexAsync(func)
Think of it as an async version of method findIndex
The findIndexAsync() method returns a promise (PrrayPromise
exactly) resolved with the index of the first element in the prray that satisfies the provided async testing function. Otherwise, it returns promise resolved with -1, indicating that no element passed the test.
const workers = Prray.from(workerArray)
const ix = await workers.findIndexAsync(checkHealth)
const unhealthy = workers[ix]
Prray.prototype.everyAsync(func, options)
Think of it as an async version of method every
The everyAsync() method tests whether all elements in the prray pass the test implemented by the provided async function. It returns a promise (PrrayPromise
exactly) that resolved with a Boolean value, 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
concurrency
Number of concurrently pending promises returned by provided function. Default:Infinity
const filenames = Prray.from(fileNameArray)
const isAllFileExisted = await filenames.everyAsync(isExisted)
if (isAllFileExisted) {
// do some things
}
Prray.prototype.someAsync(func, options)
Think of it as an async version of method some
The some() method tests whether at least one element in the prray passes the test implemented by the provided async function. It returns a promise (PrrayPromise
exactly) that resolved with Boolean value, 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
concurrency
Number of concurrently pending promises returned by provided function. Default:Infinity
const filenames = Prray.from(fileNameArray)
const hasExistedFile = await filenames.someAsync(isExisted)
if (hasExistedFile) {
// do some things
}
Prray.prototype.sortAsync(func)
Think of it as an async version of method sort
The sortAsync() method sorts the elements of a prray in place and returns a promise (PrrayPromise
exactly) resolved with the sorted prray. The provided function can be an async function that returns a promise resolved with a number.
const students = Prray.from(idArray)
const rank = await students.sortAsync((a, b) => {
const scoreA = await getScore(a)
const scoreB = await getScore(b)
return scoreA - scoreB
})
Prray.prototype.forEachAsync(func, options)
Think of it as an async version of method forEach
The forEachAsync() method executes a provided async function once for each prray element concurrently. It returns a promise (PrrayPromise
exactly) that resolved after all iteration promises resolved, 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
concurrency
Number of concurrently pending promises returned by provided function. Default:Infinity
const emails = Prray.from(emailArray)
await emails.forEachAsync(sendAsync)
// or
await emails.forEachAsync(sendAsync, { concurrency: 20 })
Other methods of Prray instance (compatible with Array)
- Prray.prototype.map(func)
- Prray.prototype.filter(func)
- Prray.prototype.reduce(func, initialValue)
- Prray.prototype.reduceRight(func, initialValue)
- Prray.prototype.find(func)
- Prray.prototype.findIndex(func)
- Prray.prototype.every(func)
- Prray.prototype.some(func)
- Prray.prototype.sort(func)
- Prray.prototype.forEach(func)
- Prray.prototype.slice(start, end)
- Prray.prototype.includes(value)
- Prray.prototype.indexOf(value)
- Prray.prototype.lastIndexOf(value)
- Prray.prototype.join(separator)
- Prray.prototype.keys()
- Prray.prototype.values()
- Prray.prototype.entries()
- Prray.prototype.fill(value, start, end)
- Prray.prototype.concat(arr)
- Prray.prototype.copyWithin(target, star, end)
- Prray.prototype.pop()
- Prray.prototype.push(...elements)
- Prray.prototype.reverse()
- Prray.prototype.shift()
- Prray.prototype.unshift(...elements)
- Prray.prototype.splice(start, deleteCount, ...items)
- Prray.prototype.toString()
- Prray.prototype.toLocaleString()
Prray.prototype.map(func)
_Compatible with Array.prototype.map_ but returns a Prray instance.
The map() method creates a new prray with the results of calling a provided function on every element in the calling prray.
Prray.prototype.filter(func)
_Compatible with Array.prototype.filter_ but returns a Prray instance.
The filter() method creates a new prray with all elements that pass the test implemented by the provided function.
Prray.prototype.reduce(func, initialValue)
_Compatible with Array.prototype.reduce_.
The reduce() method executes a reducer function (that you provide) on each element of the prray, resulting in a single output value.
Prray.prototype.reduceRight(func, initialValue)
_Compatible with Array.prototype.reduceRight_
The reduceRight() method applies a function against an accumulator and each value of the prray (from right-to-left) to reduce it to a single value.
Prray.prototype.find(func)
_Compatible with Array.prototype.find_
The find() method returns the value of the first element in the prray that satisfies the provided testing function.
Prray.prototype.findIndex(func)
_Compatible with Array.prototype.findIndex_
The findIndex() method returns the index of the first element in the prray that satisfies the provided testing function. Otherwise, it returns -1, indicating that no element passed the test.
Prray.prototype.every(func)
_Compatible with Array.prototype.every_
The every() method tests whether all elements in the prray pass the test implemented by the provided function. It returns a Boolean value.
Prray.prototype.some(func)
_Compatible with Array.prototype.some_
The some() method tests whether at least one element in the prray passes the test implemented by the provided function. It returns a Boolean value.
Prray.prototype.sort(func)
_Compatible with Array.prototype.sort_
The sort() method sorts the elements of a prray in place and returns the sorted prray.
Prray.prototype.forEach(func)
_Compatible with Array.prototype.forEach_
The forEach() method executes a provided function once for each prray element.
Prray.prototype.slice(start, end)
_Compatible with Array.prototype.slice_ but returns a Prray instance
The slice() method returns a shallow copy of a portion of a prray into a new prray object selected from begin to end (end not included) where begin and end represent the index of items in that prray. The original prray will not be modified.
Prray.prototype.includes(value)
_Compatible with Array.prototype.includes_
The includes() method determines whether a prray includes a certain value among its entries, returning true or false as appropriate.
Prray.prototype.indexOf(value)
_Compatible with Array.prototype.indexOf_
The indexOf() method returns the first index at which a given element can be found in the prray, or -1 if it is not present.
Prray.prototype.lastIndexOf(value)
_Compatible with Array.prototype.lastIndexOf_
The lastIndexOf() method returns the last index at which a given element can be found in the prray, or -1 if it is not present. The prray is searched backwards, starting at fromIndex.
Prray.prototype.join(separator)
_Compatible with Array.prototype.join_
The join() method creates and returns a new string by concatenating all of the elements in a prray (or an array-like object), separated by commas or a specified separator string. If the prray has only one item, then that item will be returned without using the separator.
Prray.prototype.keys()
_Compatible with Array.prototype.keys_
The keys() method returns a new Array Iterator object that contains the keys for each index in the prray.
Prray.prototype.values()
_Compatible with Array.prototype.values_
The values() method returns a new Array Iterator object that contains the values for each index in the prray.
Prray.prototype.entries()
_Compatible with Array.prototype.entries_
The entries() method returns a new Array Iterator object that contains the key/value pairs for each index in the prray.
Prray.prototype.fill(value, start, end)
_Compatible with Array.prototype.fill_
The fill() method fills (modifies) all the elements of a prray from a start index (default zero) to an end index (default array length) with a static value. It returns the modified prray.
Prray.prototype.concat(arr)
_Compatible with Array.prototype.concat_ but returns a Prray instance
The concat() method is used to merge two or more prrays and arrays. This method does not change the existing prrays, but instead returns a new prray.
Prray.prototype.copyWithin(target, star, end)
_Compatible with Array.prototype.copyWithin_
The copyWithin() method shallow copies part of a prray to another location in the same prray and returns it without modifying its length.
Prray.prototype.pop()
_Compatible with Array.prototype.pop_
The pop() method removes the last element from a prray and returns that element. This method changes the length of the prray.
Prray.prototype.push(...elements)
_Compatible with Array.prototype.push_
The push() method adds one or more elements to the end of a prray and returns the new length of the prray.
Prray.prototype.reverse()
_Compatible with Array.prototype.reverse_
The reverse() method reverses a prray in place. The first prray element becomes the last, and the last prray element becomes the first.
Prray.prototype.shift()
_Compatible with Array.prototype.shift_
The shift() method removes the first element from a prray and returns that removed element. This method changes the length of the prray.
Prray.prototype.unshift(...elements)
_Compatible with Array.prototype.unshift_
The unshift() method adds one or more elements to the beginning of a prray and returns the new length of the prray.
Prray.prototype.splice(start, deleteCount, ...items)
_Compatible with Array.prototype.splice_ but returns a Prray instance.
The splice() method changes the contents of a prray by removing or replacing existing elements and/or adding new elements in place.
Prray.prototype.toString()
_Compatible with Array.prototype.toString_
The toString() method returns a string representing the specified prray and its elements.
Prray.prototype.toLocaleString()
_Compatible with Array.prototype.toLocaleString_
The toLocaleString() method returns a string representing the elements of the prray. The elements are converted to Strings using their toLocaleString methods and these Strings are separated by a locale-specific String (such as a comma “,”).
Why not bluebird
Bluebird and prray have different concerns, so it may not be suitable for comparison. If you must compare, can also try:
- Prray focuses on arrays, Bluebird focuses on promises
- Bluebird has some methods such as
map
, but prray has more:findAsync
,everyAsync
, etc - Prray supports async method chaining, but for bluebird, you have to:
Bluebird.map(await Bluebird.map(arr,func1), func2)
- Prray is based on native promise implementation, and bluebird provides a good third-party promise implementation
License
MIT