Skip to content

Commit

Permalink
feat: 🎸 implement timeout() utility
Browse files Browse the repository at this point in the history
  • Loading branch information
streamich committed Apr 28, 2024
1 parent f7cb132 commit 05c5339
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 1 deletion.
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module.exports = {
verbose: true,
testURL: 'http://localhost/',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
transform: {
'^.+\.tsx?$': 'ts-jest',
Expand Down
39 changes: 39 additions & 0 deletions src/__tests__/timeout.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {timeout} from '../timeout';
import {tick} from '../tick';

test('returns result of the function', async () => {
const res = await timeout(1000, async () => 123);
expect(res).toBe(123);
});

test('returns result of the function - 2', async () => {
const res = await timeout(1000, async () => {
await tick(15);
return '123';
});
expect(res).toBe('123');
});

test('returns result of the promise', async () => {
const promise = (async () => {
await tick(15);
return '123';
})();
const res = await timeout(1000, promise);
expect(res).toBe('123');
});

test('throws TIMEOUT when running longer than timeout time', async () => {
const start = Date.now();
try {
await timeout(20, async () => {
await tick(500);
return '123';
});
throw 'not this';
} catch (error) {
expect(error).toEqual(new Error('TIMEOUT'));
const end = Date.now();
expect(end - start < 100).toBe(true);
}
});
29 changes: 29 additions & 0 deletions src/timeout.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type {Code} from "./types";

/**
* Waits for given number of milliseconds before timing out. If provided code
* block does not complete within the given time, the promise will be rejected
* with `new Error('TIMEOUT')` error.
*
* ```ts
* const result = await timeout(1000, async () => {
* return 123;
* });
* ```
*
* @param ms Number of milliseconds to wait before timing out.
* @param code Code block or promise to execute.
* @returns The result of the code block or promise.
*/
export const timeout = <T>(ms: number, code: Code<T> | Promise<T>): Promise<T> =>
new Promise<T>((resolve, reject) => {
const timer: any = setTimeout(() => reject(new Error('TIMEOUT')), ms);
const promise = typeof code === 'function' ? code() : code;
promise.then((result) => {
clearTimeout(timer);
resolve(result);
}, (error) => {
clearTimeout(timer);
reject(error);
});
});

0 comments on commit 05c5339

Please sign in to comment.