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

# 异步任务

> 创建并轮询耗时较长的生成任务。

视频、部分图像和音乐模型采用异步任务模式。创建接口会先返回任务 ID，生成结果随后才可用。

<Steps>
  <Step title="创建任务">
    调用目标模型的生成接口，并保存响应中的任务 ID。不同接口可能使用 `id`、`task_id` 或 `taskId` 字段。
  </Step>

  <Step title="查询任务">
    使用对应的任务查询接口轮询状态。建议从 2 至 5 秒的间隔开始，并使用指数退避。
  </Step>

  <Step title="读取结果">
    当状态变为成功时，读取响应中的资源 URL。资源链接可能有有效期，请及时下载或转存。
  </Step>
</Steps>

## 推荐的轮询策略

```javascript theme={null}
const successStates = new Set(["succeeded", "success", "completed"]);
const failureStates = new Set(["failed", "failure", "cancelled", "canceled"]);
const retryableStatuses = new Set([429, 502, 503, 504]);

async function pollTask(taskUrl, timeoutMs = 5 * 60 * 1000) {
  const deadline = Date.now() + timeoutMs;
  let delay = 2000;

  while (Date.now() < deadline) {
    const response = await fetch(taskUrl, {
      headers: { Authorization: `Bearer ${process.env.MAXAPI_API_KEY}` },
    });

    if (!response.ok && !retryableStatuses.has(response.status)) {
      throw new Error(`Task query failed with HTTP ${response.status}`);
    }

    if (response.ok) {
      const task = await response.json();
      const status = String(task.status).toLowerCase();

      if (successStates.has(status)) return task;
      if (failureStates.has(status)) {
        throw new Error(task.fail_reason || `Task ended with status: ${status}`);
      }
    }

    const jitter = Math.floor(Math.random() * 500);
    await new Promise((resolve) => setTimeout(resolve, delay + jitter));
    delay = Math.min(Math.round(delay * 1.5), 10000);
  }

  throw new Error("Task polling timed out");
}
```

<Warning>
  各模型的状态字段和值并不完全一致。请以创建接口和查询接口的响应定义为准，不要跨模型复用未经适配的判断逻辑。
</Warning>

## 生产环境建议

* 为轮询设置最大等待时间，避免任务永久占用工作线程。
* 对 `429` 和 `5xx` 响应执行带随机抖动的指数退避。
* 仅重试查询请求。重试创建请求前，先确认接口是否支持幂等。
* 保存任务 ID、模型名称和创建时间，便于恢复中断的任务。
* 不要把临时资源 URL 当作永久存储地址。

## 排查任务问题

| 现象           | 处理方式                                   |
| ------------ | -------------------------------------- |
| 查询接口返回 `404` | 确认任务 ID 和查询接口来自同一接口族                   |
| 状态一直不变       | 降低轮询频率，并检查接口页是否定义了排队状态                 |
| 任务失败         | 记录失败原因、请求 ID、模型 ID 和任务 ID，不要记录 API Key |
| 已成功但链接失效     | 重新查询任务；拿到结果后及时下载或转存                    |
