Skip to content

Commit

Permalink
V3.1.0 (#20)
Browse files Browse the repository at this point in the history
* added additional tests and chainable basic

* rename the methods

* rename the method names

* fix renames

* fix test for rename

* added tests and initial value usage to chainable

* Adjust logic bit

* Adjust comment bit

* update the package.json

* update tests

* change callStack to callQueue and added a new test case

* fix comments

* added implicit and explicit processing for chaining

* updated the read me and tests

* updated the read me and tests

* updated the read me

* updated the read me

* updated the read me

* updated the read me
  • Loading branch information
rpgeeganage authored Dec 26, 2018
1 parent a14c676 commit 9247dfb
Show file tree
Hide file tree
Showing 21 changed files with 901 additions and 88 deletions.
215 changes: 164 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Async-Ray
[![License](https://img.shields.io/npm/l/async-ray.svg)](https://img.shields.io/npm/l/async-ray.svg)
[![Version](https://img.shields.io/npm/v/async-ray.svg)](https://img.shields.io/npm/v/async-ray.svg)
[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/rpgeeganage/async-ray.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/rpgeeganage/async-ray/context:javascript)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/967e339f9fdb4424a48ba37a0292f221)](https://app.codacy.com/app/rpgeeganage/async-ray?utm_source=github.com&utm_medium=referral&utm_content=rpgeeganage/async-ray&utm_campaign=Badge_Grade_Settings)
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/3e1503ed17af4dc5aadb1fbbc41191d3)](https://www.codacy.com/app/rpgeeganage/async-ray?utm_source=github.com&utm_medium=referral&utm_content=rpgeeganage/async-ray&utm_campaign=Badge_Coverage)
Expand All @@ -10,6 +12,12 @@ Purpose of this package is to provide `async/await` callbacks for `every`, `filt

### TypeScript Doc: [https://rpgeeganage.github.io/async-ray/doc/](https://rpgeeganage.github.io/async-ray/doc/)

### Content
* [ ***Basic Usage*** ](#basic-usage)
* [ ***Supported methods*** ](#supported-methods)
* [ ***Using methods individually*** ](#using-methods-individually)
* [ ***Chaining*** ](#chaining)

## Basic usage

```js
Expand All @@ -27,7 +35,6 @@ const { AsyncRay } = require('async-ray');
* [ ***.aReduceRight*** ](#areduceright)
* [ ***.aSome*** ](#asome)

## Methods
### .aEvery

##### .aEvery(async callback(element[, index[, array]]))
Expand Down Expand Up @@ -231,74 +238,180 @@ const output = await AsyncRay(inputArray).aSome(
console.log(output);
// Output is true
```
## Using methods individually
You can use each method without creating ```AsyncRay ``` object.
```js
import {
aEvery, aFilter, aFind, aFindIndex,
aForEach, aMap, aReduce, aReduceRight, aSome
} from 'async-ray';

// aEvery
const everyResult = await aEvery(
[1, 2, 3],
async (e) => Promise.resolve(e > 0)
);

## Chaining

## Between AsyncRay methods
// aFilter
const filterResult = await aFilter(
[1, 2, 3],
async (e) => Promise.resolve(e > 1)
);

### **Only** `.aFilter` and `.aMap` may be chained together.
// aFind
const findResult = await aFind(
[1, 2, 3],
async (e) => Promise.resolve(e === 3)
);

Make sure to put before each AsyncRay method call an `await` (or call `.then(...)`) since a Promise is returned by the async methods.
// aFindIndex
const findIndexResult = await aFindIndex(
[1, 2, 3],
async (e) => Promise.resolve(e === 2)
);

#### sample
```js
await(await AsyncRay([1,2,3])
.aFilter(...))
.Map(...)
```
// aForEach
const forEachResult: number[] = [];
await aForEach(
[1, 2, 3],
async (e) => {
const op = await Promise.resolve(e * 10);
forEachResult.push(op);
}
);

// aMap
const mapResult = await aMap(
[1, 2, 3],
async (e) => Promise.resolve(e * 10)
);

## Between other [Array methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#) methods
// aReduce
const reduceResult = await aReduce(
[1, 2, 3],
async (acc, e) => Promise.resolve(e + acc),
0
);

`.aEvery`, `.aFilter`, `.aFind`,`.aFindIndex`, `.aForEach`, `.aMap`, `aReduce`, `aReduceRight` and `.aSome` can be chained with other [Array methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#).
// aReduceRight
const reduceRightResult = await aReduceRight(
[1, 2, 3],
async (acc, e) => Promise.resolve(e + acc),
0
);

#### sample 1 - `aMap` and `filter`
// aSome
const someResult = await aSome(
[1, 2, 3],
async (e) => Promise.resolve(e > 1)
);
```
## Chaining

### Async-Ray methods can be chained using ```Chain``` functionality
### Basic usage
```js
async function dummy(ele) {
return Promise.resolve(ele);
}

const inputArray = [1, 2, 3, 4];

const chainedValue = (await AsyncRay(inputArray).aMap(
async (ele) => await dummy(ele * 10)
)).filter((ele) => ele > 20);

console.log('Output is ', chainedValue);
// Output is [30, 40]
const { Chain } = require('async-ray');
```
---
***Chaining will return an instance of Async-Ray if returned type is an array.***

#### sample 2 - `aMap` and `find`
---

#### sample 1 - `aMap()` and `aFilter()`
---
The `process()` method __***must be called explicitly***__ to process the chain because `aMap()` and `aFilter()` method returns an array.
```js
async function dummy(ele) {
return Promise.resolve(ele);
}
const input = [1, 2, 3];

const op = await Chain(input)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.aFilter(
async (e) => Promise.resolve(e > 10)
)
.aMap(
async (e) => Promise.resolve(e * 10)
)
// Call the process() method to execute the chain
.process();

console.log('Output is ', op);
// Output is [ 200, 300 ]
```
#### sample 2 - `aMap()`, `aFilter()` and `aFind()`
---
The `process()` method __***not be called***__ to because `aFind()` does not return an array.
```js
const input = [1, 2, 3];

const op = await Chain(input)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.aFilter(
async (e) => Promise.resolve(e > 10)
)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.aFind(
async (e) => Promise.resolve(e === 300)
);
// No need to call process() method

console.log('Output is ', op);
// Output is 300
```

const inputArray = [1, 2, 3, 4];
#### Between other [Array methods](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#) methods

const chainedValue = (await AsyncRay(inputArray).aMap(
async (ele) => await dummy(ele * 10)
)).find((ele) => ele === 20);
---

console.log('Output is ', chainedValue);
// Output is 20
#### Sample 1 - Async-Ray `Chain` with `filter()`
```js
const input = [1, 2, 3];

const op = (
await Chain(input)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.aFilter(
async (e) => Promise.resolve(e > 10)
)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.process()
)
.filter(e => e > 200)

console.log('Output is ', op);
// Output is [ 300 ]
```
---

#### sample 3 - `aMap` and `reduce`

#### Sample 2 - Async-Ray `Chain` with `find()`
```js
async function dummy(ele) {
return Promise.resolve(ele);
}

const inputArray = [1, 2, 3, 4];

const chainedValue = (await AsyncRay(inputArray).aMap(
async (ele) => await dummy(ele * 10)
)).reduce((acc, ele) => acc + ele), 1);

console.log('Output is ', chainedValue);
// Output is 101
const input = [1, 2, 3];

const op = (
await Chain(input)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.aFilter(
async (e) => Promise.resolve(e > 10)
)
.aMap(
async (e) => Promise.resolve(e * 10)
)
.process()
)
.find(e => e === 200)

console.log('Output is ', op);
// Output is 200
```
34 changes: 24 additions & 10 deletions lib/async_ray.ts → lib/async_array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,21 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
constructor(...args: T[]) {
super(...args);
/***
* Why we need this ?
* if we pass one element array with an number as below,
* const foo = AsyncArray(...[20]);
* Based https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#Syntax
* a new Array will be created with 20 empty elements, as below.
* [null, null, ...]
* In order to avoid that, we need the particular workaround
*/
if (args.length === 1 && typeof args[0] === 'number') {
super(1);
super[0] = args[0];
} else {
super(...args);
}
}

/**
Expand All @@ -25,7 +39,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aEvery(cb: Methods.CallBackFilter<T>): Promise<boolean> {
return Methods.every<T>(this, cb);
return Methods.aEvery<T>(this, cb);
}

/**
Expand All @@ -36,7 +50,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aFilter(cb: Methods.CallBackFilter<T>): Promise<AsyncArray<T>> {
return new AsyncArray(...(await Methods.filter<T>(this, cb)));
return new AsyncArray(...(await Methods.aFilter<T>(this, cb)));
}

/**
Expand All @@ -47,7 +61,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aFind(cb: Methods.CallBackFind<T>): Promise<T | undefined> {
return Methods.find<T>(this, cb);
return Methods.aFind<T>(this, cb);
}

/**
Expand All @@ -58,7 +72,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aFindIndex(cb: Methods.CallBackFindIndex<T>): Promise<number> {
return Methods.findIndex<T>(this, cb);
return Methods.aFindIndex<T>(this, cb);
}

/**
Expand All @@ -69,7 +83,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aForEach(cb: Methods.CallBackForEach<T>): Promise<void> {
await Methods.forEach<T>(this, cb);
await Methods.aForEach<T>(this, cb);
}

/**
Expand All @@ -81,7 +95,7 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aMap<R>(cb: Methods.CallBackMap<T, R>): Promise<AsyncArray<R>> {
return new AsyncArray(...(await Methods.map<T, R>(this, cb)));
return new AsyncArray(...(await Methods.aMap<T, R>(this, cb)));
}

/**
Expand All @@ -97,7 +111,7 @@ export class AsyncArray<T> extends Array<T> {
cb: Methods.CallBackReduce<T, R>,
initialValue?: R
): Promise<T | R> {
return Methods.reduce(this, cb, initialValue);
return Methods.aReduce(this, cb, initialValue);
}

/**
Expand All @@ -113,7 +127,7 @@ export class AsyncArray<T> extends Array<T> {
cb: Methods.CallBackReduceRight<T, R>,
initialValue?: R
): Promise<T | R> {
return Methods.reduceRight(this, cb, initialValue);
return Methods.aReduceRight(this, cb, initialValue);
}

/**
Expand All @@ -124,6 +138,6 @@ export class AsyncArray<T> extends Array<T> {
* @memberof AsyncArray
*/
async aSome(cb: Methods.CallBackFilter<T>): Promise<boolean> {
return Methods.some<T>(this, cb);
return Methods.aSome<T>(this, cb);
}
}
Loading

0 comments on commit 9247dfb

Please sign in to comment.