ReactJS中如何轮询API直至Celery异步任务完成?
React轮询Celery异步任务实现方案
首先需要补充状态来跟踪任务状态、结果以及轮询状态,然后通过**递归setTimeout**实现轮询(前端不能用循环sleep,会阻塞主线程),同时注意清理定时器避免内存泄漏。以下是完整实现代码:
import { useEffect, useState } from "react" import axios from "axios" function App() { const [taskId, setTaskId] = useState("") const [taskStatus, setTaskStatus] = useState("PENDING") // 初始为等待状态 const [taskResult, setTaskResult] = useState(null) const [pollingTimer, setPollingTimer] = useState(null) // 存储定时器ID用于清理 // 启动Celery任务 const apiToSpawnTask = () => { axios.get("http://localhost:8000/spawn_task") .then(({data}) => { setTaskId(data.task_id) setTaskStatus("PENDING") // 重置状态 }) .catch(err => console.error("启动任务失败:", err)) } // 查询任务状态 const checkTaskStatus = () => { if (!taskId) return axios.get(`http://localhost:8000/task-id/${taskId}`) .then(({data}) => { setTaskStatus(data.status) // 根据状态处理 switch(data.status) { case "SUCCESS": // 任务完成,停止轮询并获取结果 clearTimeout(pollingTimer) getCompletedTaskResult() break case "FAILURE": // 任务失败,停止轮询 clearTimeout(pollingTimer) console.error("任务执行失败") break default: // 任务未完成,继续轮询(间隔2秒,可根据需求调整) setPollingTimer(setTimeout(checkTaskStatus, 2000)) } }) .catch(err => { console.error("查询状态失败:", err) // 失败后停止轮询,也可根据需求添加重试逻辑 clearTimeout(pollingTimer) }) } // 获取任务结果 const getCompletedTaskResult = () => { axios.get(`http://localhost:8000/get-task-result/${taskId}`) .then(({data}) => { setTaskResult(data) console.log("任务结果:", data) }) .catch(err => console.error("获取结果失败:", err)) } useEffect(() => { // 页面加载时启动任务 apiToSpawnTask() // 当taskId生成且任务处于等待状态时,启动第一轮询 if (taskId && taskStatus === "PENDING") { // 延迟1秒启动,避免任务还未注册到Celery const timer = setTimeout(checkTaskStatus, 1000) setPollingTimer(timer) } // 组件卸载时清理定时器,防止内存泄漏 return () => { if (pollingTimer) clearTimeout(pollingTimer) } }, [taskId, taskStatus]) // 依赖taskId和taskStatus,状态变化时重新触发逻辑 return ( <div> <h2>Celery任务状态: {taskStatus}</h2> {taskResult && ( <div> <h3>任务结果:</h3> <pre>{JSON.stringify(taskResult, null, 2)}</pre> </div> )} </div> ) } export default App
关键说明:
- 用**递归
setTimeout**替代setInterval:确保上一次状态请求返回后再发起下一次,避免并发请求导致的状态混乱 - 定时器清理:组件卸载或任务完成/失败时,及时清理定时器,防止内存泄漏
- 状态跟踪:通过
taskStatus和taskResult状态,在页面上实时展示任务进度和结果 - 错误处理:每个API请求都添加
catch,避免前端因接口报错崩溃
内容的提问来源于stack exchange,提问作者Phoenix
相关产品推荐
相关产品推荐

