import {Meta} from '@storybook/addon-docs/blocks'

<Meta title='@dxtmisha/vi/functional-basic/Classes/ApiPreparation - Chuẩn bị yêu cầu API'/>

# Lớp ApiPreparation

Một lớp chuyên dụng được thiết kế để xử lý các tác vụ và hiệu ứng phụ ngay trước và sau khi thực thi một yêu cầu API. Nó phục vụ việc chặn các yêu cầu trên toàn cục thông qua các hook theo dõi, cho phép thao tác trạng thái hoặc kích hoạt logic toàn cục như làm mới token hoặc ghi log.

> `ApiPreparation` là một **lớp bổ trợ** (auxiliary class), được thiết kế để quản lý vòng đời yêu cầu. Trong hầu hết các trường hợp, bạn nên tương tác với các hook thông qua các phương thức `setPreparation` và `setEnd` của thực thể `Api` chính.

## Các tính năng chính

- **Thực thi tuần tự** — đảm bảo rằng các hook chuẩn bị được giải quyết từng cái một, ngăn chặn xung đột trong các hoạt động đồng thời (ví dụ: làm mới token bị trùng lặp).
- **Chặn luồng toàn cục** — cung cấp một điểm vào và ra duy nhất cho tất cả lưu lượng mạng được khởi tạo bởi trình quản lý cha của nó.
- **Phát lại yêu cầu** — các hook sau yêu cầu có thể báo hiệu hệ thống tự động thử lại một yêu cầu sau khi trạng thái thay đổi.

## Các phương thức

### Hành động

#### `make`

Thực thi callback chuẩn bị đã đăng ký. Nếu một quá trình chuẩn bị khác đang diễn ra, nó sẽ đợi cho đến khi hoàn thành.

**Tham số:**
- `active: boolean` — Hook có được bật cho yêu cầu hiện tại hay không.
- `apiFetch: ApiFetch` — Cấu hình cho yêu cầu sắp tới.

**Trả về:** `Promise<void>`

#### `makeEnd`

Thực thi callback phân tích đã đăng ký sau khi một yêu cầu hoàn thành.

**Tham số:**
- `active: boolean` — Hook có được bật cho yêu cầu hiện tại hay không.
- `query: Response` — Đối tượng phản hồi Fetch API gốc.
- `apiFetch: ApiFetch` — Cấu hình đã được sử dụng cho yêu cầu.

**Trả về:** `Promise<ApiPreparationEnd>` — Một đối tượng điều khiển các bước tiếp theo (ví dụ: reset, tiêm dữ liệu).

### Cấu hình

- `set(callback: (apiFetch: ApiFetch) => Promise<void>): this` — Đăng ký một hàm sẽ chạy trước mọi yêu cầu được bật.
- `setEnd(callback: (query: Response, apiFetch: ApiFetch) => Promise<ApiPreparationEnd>): this` — Đăng ký một hàm sẽ chạy sau mọi phản hồi được bật.

## Các kiểu dữ liệu

#### `ApiPreparationEnd`
Kết quả thực thi của hook phân tích.
- `reset?: boolean` — Nếu true, yêu cầu sẽ bị hủy và khởi động lại.
- `data?: any` — Dữ liệu tùy chỉnh để truyền đi.

## Hướng dẫn: Cơ chế của Hook

Các quy tắc và điều kiện sau đây xác định cách hệ thống chuẩn bị đồng bộ hóa và quản lý các hook vòng đời:

- **Đồng bộ hóa** — hệ thống sử dụng cơ chế thăm dò (khoảng thời gian 160ms) để đảm bảo rằng chỉ có một hook `setPreparation` thực thi tại một thời điểm. Nếu nhiều yêu cầu bắt đầu đồng thời, các cuộc gọi tiếp theo sẽ đợi tối đa 32 lần thăm dò (~5 giây) để cuộc gọi đầu tiên hoàn thành.
- **Tiêm ngữ cảnh** — đối tượng `apiFetch` được truyền vào các hook theo dạng tham chiếu. Việc sửa đổi các thuộc tính của nó (như tiêu đề hoặc thân yêu cầu) bên trong `setPreparation` sẽ ảnh hưởng trực tiếp đến lệnh gọi mạng vật lý ngay sau đó.
- **Điều khiển luồng (Reset)** — hook `setEnd` có thể trả về `{ reset: true }`. Khi cờ này được phát hiện, `ApiInstance` sẽ hủy chuỗi yêu cầu hiện tại và khởi động lại nó ngay lập tức từ giai đoạn chuẩn bị. Điều này chủ yếu được sử dụng để làm mới token tự động và thầm lặng.
- **Phạm vi thực thi** — các hook chỉ chạy nếu chúng được bật rõ ràng trong cấu hình yêu cầu. Theo mặc định, `globalPreparation` và `globalEnd` được đặt thành true trong `ApiFetch`.
