Skip to content

Commit

Permalink
- If all functions that are passed to concurrently have the same pa…
Browse files Browse the repository at this point in the history
…rameter types then single parameter can be passed and it will be spreaded between all functions.

- Fix passing an array as single parameter to `sequentially`.
  • Loading branch information
Kapelianovych committed Sep 7, 2021
1 parent be3d216 commit 49f49ee
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 14 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

### Changed

- if functions that are passed to `sequentially` have the same parameters type then them can be passed only as single argument.
- if functions that are passed to `sequentially` or `concurrently` have the same parameters type then them can be passed only as single argument.

## [0.34.1] - 2021-09-05

Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,11 @@ function concurrently<
>(
...fns: F
): (
...args: NArray.Flatten<NArray.TrimLastEmpty<NFn.ParametersOf<F>>>
...args: If<
NArray.IsSameInnerType<ConcurrentlyParameters<F>>,
ConcurrentlyParameters<F> | [NArray.First<ConcurrentlyParameters<F>>],
ConcurrentlyParameters<F>
>
) => Promise<NFn.ReturnTypesOf<F>>;
```
Expand Down
28 changes: 21 additions & 7 deletions src/concurrently.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
import { array } from './array';
import { isPromise } from './is_promise';
import { NArray, NFn } from './utilities';
import { If, NArray, NFn } from './utilities';

type ConcurrentlyParameters<V extends ReadonlyArray<any>> = NArray.Flatten<
NArray.TrimLastEmpty<NFn.ParametersOf<V>>
>;

/** Executes functions simultaneously and can return arrays of execution results. */
export const concurrently =
<F extends ReadonlyArray<(...args: ReadonlyArray<any>) => any>>(...fns: F) =>
async (
...args: NArray.Flatten<NArray.TrimLastEmpty<NFn.ParametersOf<F>>>
): Promise<NFn.ReturnTypesOf<F>> =>
Promise.all(
...args: If<
NArray.IsSameInnerType<ConcurrentlyParameters<F>>,
ConcurrentlyParameters<F> | [NArray.First<ConcurrentlyParameters<F>>],
ConcurrentlyParameters<F>
>
): Promise<NFn.ReturnTypesOf<F>> => {
const parameters =
(args as any[]).length === 0
? fns.map(() => [])
: (args as any[]).length === 1
? fns.map(() => array((args as any[])[0]))
: (args as any[]).map((value) => array(value));

return Promise.all(
fns.map(
(fn, index) =>
new Promise((resolve, reject) => {
const parameters = array((args as any[])[index]);

try {
const result = fn(...parameters);
const result = fn(...parameters[index]);
isPromise(result)
? result.then(resolve, reject)
: resolve(result);
Expand All @@ -25,3 +38,4 @@ export const concurrently =
}),
),
) as NFn.ReturnTypesOf<F>;
};
2 changes: 1 addition & 1 deletion src/sequentially.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const sequentially =
(values as any[]).length === 0
? fns.map(() => [])
: (values as any[]).length === 1
? fns.map(() => values)
? fns.map(() => array((values as any[])[0]))
: (values as any[]).map((value) => array(value));

return fns.reduce(
Expand Down
34 changes: 30 additions & 4 deletions test/concurrently.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('concurrently', () => {
it('should handle synchronous functions with asynchronous ones', async () => {
const fn = concurrently(
(n: number) => n,
async (n: number) => n ** 2
async (n: number) => n ** 2,
);

const result = await fn(3, 4);
Expand All @@ -30,7 +30,7 @@ describe('concurrently', () => {
it('should not accept arguments for last function that does not have parameters', async () => {
const fn = concurrently(
(n: number) => n,
() => 2
() => 2,
);

const result = await fn(3);
Expand All @@ -41,7 +41,7 @@ describe('concurrently', () => {
it('should accept empty array as arguments for not last function that does not have parameters', async () => {
const fn = concurrently(
() => 2,
async (n: number) => n ** 2
async (n: number) => n ** 2,
);

const result = await fn([], 4);
Expand All @@ -52,11 +52,37 @@ describe('concurrently', () => {
it('should accept array of values when function have two or more parameters', async () => {
const fn = concurrently(
(n: number) => n,
(n: number, a: number) => n ** 2 * 3
(n: number, _a: number) => n ** 2 * 3,
);

const result = await fn(3, [4, 6]);

expect(result).toEqual([3, 48]);
});

it('should accept one argument if all functions have one parameter of the same type', () => {
const fn = concurrently(
(n: number) => n ** 2,
(n: number) => n + ' attempt.',
);

const result = fn(3);

expect(result).resolves.toEqual([9, '3 attempt.']);
});

it(
'should accept one argument as an array if all functions have ' +
'several parameters with the same type',
async () => {
const fn = concurrently(
(n: number, s: string) => n + s,
(n: number, s: string) => s + n,
);

const result = await fn([1, '2']);

expect(result).toEqual(['12', '21']);
},
);
});
11 changes: 11 additions & 0 deletions test/sequentially.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,4 +142,15 @@ describe('sequentially', () => {

expect(result).toEqual(['Hello world!', 'Hello IT!']);
});

it('should accept one array parameter if all functions have the same parameter types', () => {
const fn = sequentially(
(word: string, another: string) => word + another,
(word: string, another: string) => another + word,
);

const result = fn(['Hello', 'world']);

expect(result).toEqual(['Helloworld', 'worldHello']);
});
});

0 comments on commit 49f49ee

Please sign in to comment.