feat(withTimeout): add withTimeout function (#210)

* feat(timeout): add timeout function

* feat(timeout): timeout to withTimeout

* Update docs/ko/reference/promise/withTimeout.md

* Update docs/ko/reference/promise/withTimeout.md

* feat(timeout): timeout, withTimeout

* Update docs/ko/reference/promise/timeout.md

* Update docs/ko/reference/promise/timeout.md

* Update withTimeout.ts

* Update timeout.ts

* Apply suggestions from code review

* Update withTimeout.md

* Update withTimeout.spec.ts

* Update src/promise/withTimeout.spec.ts

---------

Co-authored-by: Sojin Park <raon0211@gmail.com>
Co-authored-by: Sojin Park <raon0211@toss.im>
This commit is contained in:
Seung Ju 2024-07-18 21:37:33 +09:00 committed by GitHub
parent 2db0b49579
commit b31b3a6964
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 262 additions and 0 deletions

View File

@ -0,0 +1,29 @@
# timeout
지정한 시간 뒤에 `TimeoutError` 에러와 함께 reject되는 `Promise`를 반환해요.
## 인터페이스
```typescript
function timeout(ms: number): Promise<never>;
```
### 파라미터
- `ms` (`number`): `TimeoutError` 에러와 함께 reject될 때까지 걸릴 밀리세컨드.
### 반환 값
(`Promise<never>`): `TimeoutError`로 reject될 Promise.
## 예시
### 기본 사용법
```typescript
try {
await timeout(1000); // 1초 뒤 TimeoutError 에러 발생
} catch (error) {
console.error(error); // 'The operation was timed out' 로깅
}
```

View File

@ -0,0 +1,32 @@
# withTimeout
지정한 시간보다 늦은 시간에 응답할 경우 `TimeoutError` 에러로 처리해요.
이 함수는 특정한 시간 이후 보다 value의 응답이 늦게 올 경우 TimeoutError로 reject되는 Promise를 반환해요. async/await 함수를 사용하는 경우에 함수의 최대 실행 시간을 정할 수 있어요.
## 인터페이스
```typescript
function withTimeout<T>(run: () => Promise<T>, ms: number): Promise<T>;
```
### 파라미터
- `run` (`() => Promise<T>`): 실행할 비동기 함수.
- `ms` (`number`): Promise의 최대 실행 값을 지정할 밀리세컨드.
### 반환 값
(`Promise<T>`): 주어진 비동기 함수가 반환하는 `Promise`.
## 예시
### 기본 사용법
```typescript
try {
await withTimeout(() => new Promise(() => {}), 1000); // 코드 최대 시간을 1초로 지정
} catch (error) {
console.error(error); // 'The operation was timed out' 로깅
}
```

View File

@ -0,0 +1,29 @@
# timeout
Returns a `Promise` that rejects with a `TimeoutError` after the specified timeout.
## Signature
```typescript
function timeout(ms: number): Promise<never>;
```
### Parameters
- `ms` (`number`): The number of milliseconds for the promise to reject with `TimeoutError`.
### Returns
(`Promise<never>`): A Promise that rejects after the specified timeout.
## 예시
### 기본 사용법
```typescript
try {
await timeout(1000); // Timeout exception after 1 second
} catch (error) {
console.error(error); // Will log 'The operation was timed out'
}
```

View File

@ -0,0 +1,33 @@
# withTimeout
Executes an async function and enforces a timeout.
If the promise does not resolve within the specified time,
the timeout will trigger and the returned promise will be rejected.
## Signature
```typescript
function withTimeout<T>(run: () => Promise<T>, ms: number): Promise<T>;
```
### Parameters
- `run` (`() => Promise<T>`): A function that returns a promise to be executed.
- `ms` (`number`): The timeout duration in milliseconds.
### Returns
(`Promise<T>`): A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
## Examples
### Basic Usage
```typescript
try {
await withTimeout(() => new Promise(() => {}), 1000); // Timeout exception after 1 second
} catch (error) {
console.error(error); // Will log 'The operation was timed out'
}
```

View File

@ -0,0 +1,31 @@
# timeout
如果响应时间晚于指定时间, 则将其视为 `TimeoutError`错误。
此函数返回一个 Promise该 Promise 在指定超时后解析,允许您使用它 使用 async/await 来超时执行。
## 签名
```typescript
function timeout(ms: number): Promise<void>;
```
### 参数
- `ms` (`number`): 指定 Promise 的最大执行值的毫秒。
### 返回值
(`Promise<T>`): 要执行的 Promise 返回值。
## 示例
### 基本用法
```typescript
try {
await timeout(1000); // 代码时间最长为 1秒
} catch (error) {
console.error(error); // 将会输出 'The operation was timed out'
}
```

View File

@ -0,0 +1,32 @@
# withTimeout
如果响应时间晚于指定时间, 则将其视为 `TimeoutError`错误。
此函数返回一个 Promise该 Promise 在指定超时后解析,允许您使用它 使用 async/await 来超时执行。
## 签名
```typescript
function withTimeout<T>(run: () => Promise<T>, ms: number): Promise<T>;
```
### 参数
- `run` (`() => Promise<T>`): 要执行的 Promise 值。
- `ms` (`number`): 指定 Promise 的最大执行值的毫秒。
### 返回值
(`Promise<T>`): 要执行的 Promise 返回值。
## 示例
### 基本用法
```typescript
try {
await withTimeout(() => new Promise(() => {}), 1000); // 代码时间最长为 1秒
} catch (error) {
console.error(error); // 将会输出 'The operation was timed out'
}
```

10
src/error/TimeoutError.ts Normal file
View File

@ -0,0 +1,10 @@
/**
* An error class representing an timeout operation.
* @augments Error
*/
export class TimeoutError extends Error {
constructor(message = 'The operation was timed out') {
super(message);
this.name = 'TimeoutError';
}
}

View File

@ -1 +1,2 @@
export { AbortError } from './AbortError.ts';
export { TimeoutError } from './TimeoutError.ts';

View File

@ -1 +1,2 @@
export { delay } from './delay.ts';
export { withTimeout } from './withTimeout.ts';

View File

@ -0,0 +1,8 @@
import { describe, expect, it } from 'vitest';
import { timeout } from './timeout.ts';
describe('timeout', () => {
it('returns a reason if a response is received after the specified wait time', () => {
expect(timeout(50)).rejects.toThrow('The operation was timed out');
});
});

14
src/promise/timeout.ts Normal file
View File

@ -0,0 +1,14 @@
import { delay } from './delay.ts';
import { TimeoutError } from '../error/TimeoutError.ts';
/**
* Returns a promise that rejects with a `TimeoutError` after a specified delay.
*
* @param {number} ms - The delay duration in milliseconds.
* @returns {Promise<void>} A promise that rejects with a `TimeoutError` after the specified delay.
* @throws {TimeoutError} Throws a `TimeoutError` after the specified delay.
*/
export async function timeout(ms: number): Promise<never> {
await delay(ms);
throw new TimeoutError();
}

View File

@ -0,0 +1,18 @@
import { describe, expect, it } from 'vitest';
import { withTimeout } from './withTimeout.ts';
import { delay } from './delay.ts';
describe('withTimeout', () => {
it('returns the result value if a response is received before the specified wait time', async () => {
const result = await withTimeout(async () => {
await delay(50);
return 'foo';
}, 100);
expect(result).toEqual('foo');
});
it('returns a reason if a response is received after the specified wait time', () => {
expect(withTimeout(() => delay(100), 50)).rejects.toThrow('The operation was timed out');
});
});

View File

@ -0,0 +1,24 @@
import { timeout } from './timeout.ts';
/**
* Executes an async function and enforces a timeout.
*
* If the promise does not resolve within the specified time,
* the timeout will trigger and the returned promise will be rejected.
*
*
* @template T
* @param {() => Promise<T>} run - A function that returns a promise to be executed.
* @param {number} ms - The timeout duration in milliseconds.
* @returns {Promise<T>} A promise that resolves with the result of the `run` function or rejects if the timeout is reached.
*
* @example
* try {
* await withTimeout(() => {}, 1000); // Timeout exception after 1 second
* } catch (error) {
* console.error(error); // Will log 'TimeoutError'
* }
*/
export async function withTimeout<T>(run: () => Promise<T>, ms: number): Promise<T> {
return Promise.race([run(), timeout(ms) as T]);
}