diff --git a/.changeset/long-lobsters-type.md b/.changeset/long-lobsters-type.md
new file mode 100644
index 000000000..566817390
--- /dev/null
+++ b/.changeset/long-lobsters-type.md
@@ -0,0 +1,5 @@
+---
+"@modern-kit/utils": patch
+---
+
+feat(utils): delay 함수 추가
diff --git a/docs/docs/utils/common/delay.md b/docs/docs/utils/common/delay.md
new file mode 100644
index 000000000..4182b7b44
--- /dev/null
+++ b/docs/docs/utils/common/delay.md
@@ -0,0 +1,24 @@
+# delay
+
+주어진 시간만큼 기다린 뒤 다음 동작을 수행할 수 있도록 하는 함수입니다.
+
+setTimeout을 사용하여 특정 시간 뒤의 동작을 정의할 경우, 해당 시간 뒤 동작해야하는 함수 다음에 Promise가 존재한다면 setTimeout은 macroTaskQueue에 속하고 Promise는 microTaskQueue에 속하게 되어 의도한 바와 같이 순서대로의 동작을 보장하지 못할 수 있습니다. delay 함수를 사용한다면 이러한 문제를 해결할 수 있습니다.
+
+
+
+## Interface
+```tsx
+const delay: (time: number) => Promise
+```
+
+## Usage
+```ts
+import { delay } from '@modern-kit/utils';
+
+const something = () => Promise.resolve()
+
+const doSomethingAfterDelay = async () => {
+ await delay(1000)
+ await something()
+}
+```
\ No newline at end of file
diff --git a/packages/react/src/hooks/useBlockPromiseMultipleClick/useBlockPromiseMultipleClick.spec.tsx b/packages/react/src/hooks/useBlockPromiseMultipleClick/useBlockPromiseMultipleClick.spec.tsx
index 46001e03c..ff59dea88 100644
--- a/packages/react/src/hooks/useBlockPromiseMultipleClick/useBlockPromiseMultipleClick.spec.tsx
+++ b/packages/react/src/hooks/useBlockPromiseMultipleClick/useBlockPromiseMultipleClick.spec.tsx
@@ -2,12 +2,7 @@ import { describe, expect, it } from 'vitest';
import { screen, renderHook } from '@testing-library/react';
import { renderSetup } from '../../utils/test/renderSetup';
import { useBlockPromiseMultipleClick } from '.';
-
-const delay = (time: number) => {
- return new Promise((resolve) => {
- setTimeout(() => resolve(), time);
- });
-};
+import { delay } from '@modern-kit/utils';
beforeEach(() => {
vi.useFakeTimers();
@@ -29,7 +24,7 @@ describe('useBlockPromiseMultipleClick', () => {
const { user } = renderSetup(
,
- { delay: null }
+ { delay: null },
);
const button = screen.getByRole('button');
diff --git a/packages/utils/src/common/delay/delay.spec.ts b/packages/utils/src/common/delay/delay.spec.ts
new file mode 100644
index 000000000..bb40c67a8
--- /dev/null
+++ b/packages/utils/src/common/delay/delay.spec.ts
@@ -0,0 +1,15 @@
+import { describe, expect, it } from 'vitest';
+import { delay } from '.';
+
+describe('delay', () => {
+ it('should delay the promise by the given time', async () => {
+ const time = 200;
+ const start = Date.now();
+
+ await delay(time);
+
+ const end = Date.now();
+
+ expect(end - start).toBeGreaterThanOrEqual(time);
+ });
+});
diff --git a/packages/utils/src/common/delay/index.ts b/packages/utils/src/common/delay/index.ts
new file mode 100644
index 000000000..ea96ebc72
--- /dev/null
+++ b/packages/utils/src/common/delay/index.ts
@@ -0,0 +1,5 @@
+export const delay = (time: number) => {
+ return new Promise((resolve) => {
+ setTimeout(() => resolve(), time);
+ });
+};
diff --git a/packages/utils/src/common/index.ts b/packages/utils/src/common/index.ts
index b2252b8d9..5f46ce6bd 100644
--- a/packages/utils/src/common/index.ts
+++ b/packages/utils/src/common/index.ts
@@ -2,6 +2,7 @@ export * from './abRandom';
export * from './asyncNoop';
export * from './deepCopy';
export * from './deepEqual';
+export * from './delay';
export * from './getUniqId';
export * from './getUniqTime';
export * from './getViewportSize';