> ## Documentation Index
> Fetch the complete documentation index at: https://docs.youka.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tác vụ

> Kiểm tra tác vụ và chờ các thao tác bất đồng bộ hoàn tất

Mọi thao tác bất đồng bộ trong Youka cuối cùng đều chạy dưới dạng một tác vụ, nhưng bề mặt SDK chính hiện trả về các handle thao tác thay vì ID tác vụ thô. Hầu hết người gọi nên dùng `client.projects.wait(...)` hoặc `client.exports.wait(...)` và chỉ dùng `client.tasks.*` khi cần kiểm tra tác vụ ở mức thấp.

## `client.tasks.get(taskId, options?)`

Lấy trạng thái hiện tại của một tác vụ theo ID.

```ts theme={null}
const task = await client.tasks.get("tsk_abc123");
console.log(task.status, task.type);
```

### Trạng thái tác vụ

| Trạng thái    | Kết thúc? | Ý nghĩa                                              |
| ------------- | --------- | ---------------------------------------------------- |
| `created`     | Không     | Tác vụ đã được tạo nhưng chưa được đưa vào hàng đợi. |
| `queued`      | Không     | Tác vụ đang chờ chạy.                                |
| `in-progress` | Không     | Tác vụ đang được thực thi.                           |
| `completed`   | Có        | Tác vụ hoàn tất thành công.                          |
| `finalized`   | Có        | Tác vụ đã xong và hậu xử lý đã hoàn tất.             |
| `failed`      | Có        | Tác vụ thất bại với một lỗi.                         |
| `cancelled`   | Có        | Tác vụ đã bị hủy.                                    |
| `timed-out`   | Có        | Tác vụ đã chạm giới hạn thời gian.                   |

## `client.tasks.wait(taskId, options?)`

Thăm dò một tác vụ cho đến khi nó đạt trạng thái kết thúc. Trả về tác vụ cuối cùng khi thành công, ném `YoukaTaskError` khi thất bại.

```ts theme={null}
const task = await client.tasks.wait("tsk_abc123", {
  pollIntervalMs: 3_000,
  signal: abortController.signal,
});
```

### Tùy chọn

<ParamField path="pollIntervalMs" type="number">
  Số mili giây giữa các lần thăm dò. Mặc định là `2000`.
</ParamField>

<ParamField path="signal" type="AbortSignal">
  Hủy việc chờ. Yêu cầu đang thực hiện và mọi khoảng trì hoãn đang chờ sẽ bị hủy
  ngay lập tức.
</ParamField>

### Lỗi

`client.tasks.wait(...)` ném `YoukaTaskError` khi tác vụ kết thúc ở `failed`, `cancelled`, hoặc `timed-out`:

```ts theme={null}
import { YoukaTaskError } from "@youka/sdk";

try {
  await client.tasks.wait("tsk_abc123");
} catch (error) {
  if (error instanceof YoukaTaskError) {
    console.error(error.code); // TASK_FAILED | TASK_CANCELLED | TASK_TIMED_OUT
    console.error(error.task); // Full RestTask payload
  }
  throw error;
}
```

## `client.projects.wait(operation, options?)`

Chờ một thao tác theo phạm vi project hoàn tất, sau đó lấy lại project. Trả về handle thao tác, tác vụ ở trạng thái kết thúc, và project đã được cập nhật.

```ts theme={null}
const operation = await client.projects.create({
  source: { type: "path", path: "./song.mp3" },
});

const { project, task } = await client.projects.wait(operation, {
  pollIntervalMs: 2_500,
});

console.log("Project ready:", project.id);
console.log("Task finished in state:", task.status);
```

<ParamField path="operation" type="ProjectOperation" required>
  Thường là kết quả của `client.projects.create(...)`,
  `client.projects.separateStems(...)`, hoặc `client.projects.syncLyrics(...)`.
</ParamField>

## `client.exports.wait(operationOrId, options?)`

Chờ một cloud export đạt trạng thái kết thúc. Truyền vào `ExportOperation` được trả về bởi `client.exports.create(...)` hoặc một chuỗi `exportId`.

```ts theme={null}
const operation = await client.exports.create("prj_abc123", {
  resolution: "1080p",
  quality: "high",
});

const finalized = await client.exports.wait(operation, {
  pollIntervalMs: 3_000,
});

console.log(finalized.status, finalized.url);
```

## Hủy

Truyền một `AbortSignal` để hủy một lần chờ chạy lâu:

```ts theme={null}
const controller = new AbortController();

setTimeout(() => controller.abort(), 60_000);

try {
  await client.projects.wait(operation, { signal: controller.signal });
} catch (error) {
  if (error instanceof Error && error.name === "AbortError") {
    console.log("Wait cancelled after 60s");
  } else {
    throw error;
  }
}
```

Cùng một signal cũng hủy yêu cầu thăm dò tác vụ hoặc export ở tầng dưới.

## Tiếp theo

* [Errors](/vi/sdk/errors) — xử lý `YoukaTaskError` và các lỗi có thể thử lại
* [Exports](/vi/sdk/exports) — chờ một export hoàn tất
* [API async jobs](/vi/api/async-jobs) — cùng một mẫu trong HTTP thô
