Skip to content

Commit

Permalink
feat(Promise): added tryOneByOne
Browse files Browse the repository at this point in the history
  • Loading branch information
alisahinozcelik committed Feb 27, 2022
1 parent 0e6850f commit 55bd3bb
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 0 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,23 @@ const promise = anAsyncCall();
const [error, result] = await tryCatch(promise);
```

#### [Try One By One](https://thalesrc.github.io/js-utils/modules/_promise_try_one_by_one_.html)
Tries a set of promises one by one with given order. Breaks the call when a promise resolved. Otherwise keeps trying incoming promises until the list is finished.

```typescript
import { tryOneByOne } from "@thalesrc/js-utils/promise";

async function fooFunction() {
const foo = await tryOneByOne([
() => someCall(),
(err) => anotherCall(),
(err) => fooPromise()
]);

// do stuff
}
```

### String

#### [Limit](https://thalesrc.github.io/js-utils/modules/_string_limit_.html)
Expand Down
1 change: 1 addition & 0 deletions src/promise/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './never';
export * from './revert';
export * from './try-catch';
export * from './try-one-by-one';
export * from './timeout';
30 changes: 30 additions & 0 deletions src/promise/static/try-one-by-one.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { tryOneByOne } from '../try-one-by-one';

declare global {
export interface PromiseConstructor {
/**
* #### Try One By One
* Tries a set of promises one by one with given order. Breaks the call when a promise resolved. Otherwise keeps trying incoming promises until the list is finished.
*
* * * *
* Example:
* ```typescript
* import "@thalesrc/js-utils/promise/static/try-one-by-one";
*
* async function fooFunction() {
* const foo = await Promise.tryOneByOne([
* () => someCall(),
* (err) => anotherCall(),
* (err) => fooPromise()
* ]);
*
* // do stuff
* }
* ```
* * * *
*/
tryOneByOne: typeof tryOneByOne;
}
}

Promise.tryOneByOne = tryOneByOne;
34 changes: 34 additions & 0 deletions src/promise/try-one-by-one.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import 'jest';

import { tryOneByOne } from './try-one-by-one';

class CustomError {
constructor(public message: string) {}
}

describe('TryOneByOne Function', () => {
it('should resolve if a promise resolved', done => {
tryOneByOne([Promise.resolve('foo')])
.then(res => {
expect(res).toBe('foo');
done();
})
.catch(err => {
throw new CustomError("didn't resolve");
});
});

it('should try the next promise when the first threw error', done => {
tryOneByOne([
Promise.reject('foo'),
Promise.resolve('bar'),
])
.then(res => {
expect(res).toBe('bar');
done();
})
.catch(err => {
throw new CustomError("didn't resolve");
});
});
});
58 changes: 58 additions & 0 deletions src/promise/try-one-by-one.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* #### Try One By One
*
* Tries a set of promises one by one with given order. Breaks the call when a promise resolved. Otherwise keeps trying incoming promises until the list is finished.
*
* * * *
* Example:
* ```typescript
* import { tryOneByOne } from "@thalesrc/js-utils/promise";
*
* async function fooFunction() {
* const foo = await tryOneByOne([
* () => someCall(),
* (err) => anotherCall(),
* (err) => fooPromise()
* ]);
*
* // do stuff
* }
*
* ```
*
* Static Example:
* ```typescript
* import "@thalesrc/js-utils/promise/static/try-one-by-one";
*
* async function fooFunction() {
* const foo = await Promise.tryOneByOne([
* () => someCall(),
* (err) => anotherCall(),
* (err) => fooPromise()
* ]);
*
* // do stuff
* }
*
* ```
* * * *
* @param promises List of promises to try one by one with the order
* @returns
*/
export async function tryOneByOne<T>(promises: Array<Promise<T> | ((lastError: unknown) => Promise<T>)>): Promise<T> {
return await tryPromises([...promises], null);
}

async function tryPromises<T>(promises: Array<Promise<T> | ((lastError: unknown) => Promise<T>)>, lastError: unknown): Promise<T> {
const promiseFn = promises.shift();

if (!promiseFn) throw lastError;

try {
const promise = typeof promiseFn === "function" ? promiseFn(lastError) : promiseFn;

return await promise;
} catch (err) {
return tryPromises(promises, err);
}
}

0 comments on commit 55bd3bb

Please sign in to comment.