Skip to content

Commit

Permalink
feat(retry): add retry
Browse files Browse the repository at this point in the history
  • Loading branch information
faner11 committed Jan 3, 2025
1 parent 32a1838 commit cfadd0c
Show file tree
Hide file tree
Showing 7 changed files with 283 additions and 0 deletions.
45 changes: 45 additions & 0 deletions docs/ja/reference/function/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# retry

この関数は再試行間隔と再試行回数を設定し、再試行の最大回数に達するとエラーをスローします。

## インターフェース

```typescript
function retry<T>(func: () => Promise<T>, options: RetryOptions): T;
```

### パラメータ

- `func` (`F`): 再試行する関数。
- `options` (`RetryOptions`): オプション オブジェクト。
- `intervalMs`: 間隔遅延のミリ秒数。
- `retries`: 再試行の回数。

### 戻り値

(`Awaited<ReturnType<F>>`): 関数の戻り値

### Error

再試行回数が `retries` に達するとエラーが発生します

##

```typescript
async function getNumber() {
return Promise.resolve(3);
}
async function getError() {
return Promise.reject(new Error('MyFailed'));
}
// 結果は3になります
await retry(getNumber, {
intervalMs: 1000,
retries: 2,
});
// 2回実行すると例外がスローされます
await retry(getError, {
intervalMs: 1000,
retries: 2,
});
```
45 changes: 45 additions & 0 deletions docs/ko/reference/function/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# retry

이 기능은 재시도 간격과 재시도 횟수를 설정하고, 최대 재시도 횟수에 도달하면 오류를 발생시킵니다.

## 인터페이스

```typescript
function retry<T>(func: () => Promise<T>, options: RetryOptions): T;
```

### 파라미터

- `func` (`F`): 다시 시도하는 기능입니다.
- `options` (`RetryOptions`): 옵션 객체.
- `intervalMs`: 간격 지연의 밀리초 수입니다.
- `retries`: 재시도 횟수입니다.

### 반환 값

(`Awaited<ReturnType<F>>`): 함수 반환 값.

### Error

재시도 횟수가 `retries`에 도달하면 오류가 발생합니다.

## 예시

```typescript
async function getNumber() {
return Promise.resolve(3);
}
async function getError() {
return Promise.reject(new Error('MyFailed'));
}
// 결과는 3이 됩니다
await retry(getNumber, {
intervalMs: 1000,
retries: 2,
});
// 2번 실행 후 예외가 발생합니다.
await retry(getError, {
intervalMs: 1000,
retries: 2,
});
```
45 changes: 45 additions & 0 deletions docs/reference/function/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# retry

This function can set the retry interval and the number of retries, and throw an Error after the maximum number of retries is reached.

## Signature

```typescript
function retry<T>(func: () => Promise<T>, options: RetryOptions): T;
```

### Parameters

- `func` (`F`): The function to retry.
- `options` (`RetryOptions`): An options object.
- `intervalMs`: The number of milliseconds to interval delay.
- `retries`: The number of retries to attemptcalled.

### Returns

(`Awaited<ReturnType<F>>`): Function return value

### Error

Throws an error if the number of retries reaches `retries`

## Examples

```typescript
async function getNumber() {
return Promise.resolve(3);
}
async function getError() {
return Promise.reject(new Error('MyFailed'));
}
// The result will be 3
await retry(getNumber, {
intervalMs: 1000,
retries: 2,
});
// After executing twice, an exception is thrown
await retry(getError, {
intervalMs: 1000,
retries: 2,
});
```
45 changes: 45 additions & 0 deletions docs/zh_hans/reference/function/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# retry

该函数可以设置重试间隔以及重试次数,达到最大重试次数后抛出Error。

## 签名

```typescript
function retry<T>(func: () => Promise<T>, options: RetryOptions): T;
```

### 参数

- `func` (`F`): 重试的功能函数
- `options` (`RetryOptions`): 选项
- `intervalMs`: 间隔延迟的毫秒数.
- `retries`: 最大重试次数.

### 返回值

(`Awaited<ReturnType<F>>`): 函数返回值

### 异常

如果重试次数达到 `retries` 则抛出错误

## 示例

```typescript
async function getNumber() {
return Promise.resolve(3);
}
async function getError() {
return Promise.reject(new Error('MyFailed'));
}
// 将返回 3
await retry(getNumber, {
intervalMs: 1000,
retries: 2,
});
// 将抛出异常
await retry(getError, {
intervalMs: 1000,
retries: 2,
});
```
1 change: 1 addition & 0 deletions src/function/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { once } from './once.ts';
export { partial } from './partial.ts';
export { partialRight } from './partialRight.ts';
export { rest } from './rest.ts';
export { retry } from './retry.ts';
export { spread } from './spread.ts';
export { throttle, type ThrottledFunction } from './throttle.ts';
export { unary } from './unary.ts';
25 changes: 25 additions & 0 deletions src/function/retry.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { describe, expect, it } from 'vitest';
import { retry } from './retry';

async function getNumber() {
return Promise.resolve(3);
}

async function getError() {
return Promise.reject(new Error('MyFailed'));
}

// Tests
describe('retry', () => {
it('Execute successfully and return value', async () => {
const num = await retry(getNumber, { intervalMs: 1000, retries: 3 });
expect(num).toBe(3);
});
it('Retry multiple times and throw an exception', async () => {
expect(retry(getError, { intervalMs: 1000, retries: 2 })).rejects.toThrowError(new Error('MyFailed'));
});

it('When retries is 0, a fallback error is triggered', async () => {
expect(retry(getError, { intervalMs: 1000, retries: 0 })).rejects.toThrowError(new Error('Failed after maximum retries'));
});
});
77 changes: 77 additions & 0 deletions src/function/retry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { delay } from '../promise';

interface RetryOptions {
/**
* The number of milliseconds to interval delay.
*/
intervalMs: number;

/**
* The number of retries to attempt
*/
retries: number;
}
/**
* Function for asynchronous retry
*
* This function can set the retry interval and the number of retries, and throw an Error after the maximum number of retries is reached.
*
* @template F - The type of the function to be invoked.
* @param {F} func - The function to be invoked.
* @param {RetryOptions} options - The options object
* @returns {Awaited<ReturnType<F>>} - Function return value
* @throws {Error} - Throws an error if the maximum number of retries is exceeded.
* @example
*
* async function getNumber() {
* return Promise.resolve(3);
* }
* async function getError() {
* return Promise.reject(new Error('MyFailed'));
* }
* // The result will be 3
* await retry(getNumber, {
* intervalMs: 1000,
* retries: 2,
* });
* // After executing twice, an exception is thrown
* await retry(getError, {
* intervalMs: 1000,
* retries: 2,
* });
*/

export async function retry<T>(func: () => Promise<T>, options: RetryOptions): Promise<T> {
const { intervalMs, retries } = options;

for (let i = 0; i < retries; i++) {
try {
return await func();
} catch (error) {
if (i === retries - 1) {
throw error;
}
await delay(intervalMs);
}
}
throw new Error('Failed after maximum retries');
}

/* async function getNumber() {
return Promise.resolve(3);
}
async function getError() {
return Promise.reject(new Error('MyFailed'));
}
// The result will be 3
await retry(getNumber, {
intervalMs: 1000,
retries: 2,
});
// After executing twice, an exception is thrown
await retry(getError, {
intervalMs: 1000,
retries: 2,
});
*/

0 comments on commit cfadd0c

Please sign in to comment.