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

# 任务轮询与素材下载

> 状态机、退避间隔、终态处理和三天素材有效期

## 状态说明

| 状态           | 是否终态 | 处理方式                        |
| ------------ | ---- | --------------------------- |
| `queued`     | 否    | 任务排队中，继续轮询。                 |
| `processing` | 否    | 正在生成，继续轮询。                  |
| `succeeded`  | 是    | 读取 `result.images` 并保存图片。   |
| `failed`     | 是    | 记录 `error`，停止轮询并决定是否修改输入重试。 |
| `cancelled`  | 是    | 任务已取消，停止轮询。                 |

## 推荐间隔

任务提交后等待 5 秒再首次查询；未完成时依次等待：

```text theme={null}
5 秒 → 8 秒 → 13 秒 → 20 秒 → 30 秒 → 之后每 30 秒一次
```

建议单个任务最长轮询 15 分钟。超过后停止前台轮询并转入后台低频检查，不要把超时直接视为任务失败。

## JavaScript 轮询示例

```javascript theme={null}
async function waitForTask(taskId, apiKey) {
  const delays = [5000, 8000, 13000, 20000, 30000];
  const startedAt = Date.now();
  let attempt = 0;

  while (Date.now() - startedAt < 15 * 60 * 1000) {
    const delay = delays[Math.min(attempt, delays.length - 1)];
    await new Promise(resolve => setTimeout(resolve, delay));

    const response = await fetch(
      `https://api.ch88.cn/v1/open/tasks/${encodeURIComponent(taskId)}`,
      { headers: { Authorization: `Bearer ${apiKey}` } },
    );

    if (response.status === 429) {
      const retryAfter = Number(response.headers.get('Retry-After')) || 30;
      await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
      continue;
    }

    if (!response.ok) {
      throw new Error(`查询失败：${response.status} ${await response.text()}`);
    }

    const responseBody = await response.json();
    const task = responseBody.data;
    if (task.status === 'succeeded') return task;
    if (task.status === 'failed' || task.status === 'cancelled') {
      throw new Error(JSON.stringify(task.error ?? { status: task.status }));
    }

    attempt += 1;
  }

  throw new Error('等待任务超时，任务可能仍在后台处理');
}
```

## 下载图片

任务成功后，`result.images[].url` 是完整临时地址，可以直接通过浏览器、`<img>` 或下载工具访问：

```bash theme={null}
curl --location '<RESULT_IMAGE_URL>' --output result.png
```

生成图片最长保留 3 天。缓存成功时，`expires_at` 会给出预计过期时间；如果该字段为 `null`，应立即下载，不要假设仍有三天。

<Warning>
  到期后平台会自动清理 R2 对象。CDN 或浏览器短期缓存命中不代表对象仍被永久保存。
</Warning>
