如何修复Flask+JavaScript长任务完成后异步更新网页的代码?
修复Flask+JS异步长任务页面更新问题
原代码核心问题
- Flask端缺少启动长任务和查询任务状态的API接口,前端无法触发后端任务也没法获取任务进度
- 前端错误使用浏览器不存在的
ThreadAPI,浏览器JS无原生Thread构造函数 - 前端未定义
taskComplete变量,也没有与后端通信获取状态的逻辑 - Flask全局变量
task_complete在多请求场景下不安全,状态存储方式需改进
修复后的完整代码
app.py
from flask import Flask, render_template, jsonify from threading import Thread import time from uuid import uuid4 app = Flask(__name__) # 用字典存储任务状态,支持多任务(比全局变量更可靠) task_status = {} def run_lengthy_task(task_id): time.sleep(60) # 模拟1分钟长任务 # 任务完成后更新状态与结果 task_status[task_id] = { "complete": True, "data": "Updated data from lengthy task" } @app.route('/') def index(): return render_template('index.html') # 启动长任务的API @app.route('/start-task') def start_task(): task_id = str(uuid4()) # 初始化任务状态为未完成 task_status[task_id] = {"complete": False, "data": ""} # 启动后台线程执行任务(daemon=True确保程序退出时线程自动结束) Thread(target=run_lengthy_task, args=(task_id,), daemon=True).start() # 返回任务ID,供前端查询状态 return jsonify({"task_id": task_id}) # 查询任务状态的API @app.route('/task-status/<task_id>') def task_status_api(task_id): status = task_status.get(task_id, {"complete": False, "data": ""}) return jsonify(status) if __name__ == '__main__': app.run(debug=True)
index.html
<html> <head> <script> let currentTaskId = null; async function startTask() { // 调用后端接口启动任务 const response = await fetch('/start-task'); const data = await response.json(); currentTaskId = data.task_id; // 启动轮询检查任务状态 updatePage(); // 禁用按钮防止重复提交 document.querySelector('button').disabled = true; } async function updatePage() { if (!currentTaskId) return; const response = await fetch(`/task-status/${currentTaskId}`); const status = await response.json(); if (status.complete) { // 任务完成,更新页面内容 document.getElementById("data").innerHTML = status.data; // 恢复按钮状态 document.querySelector('button').disabled = false; currentTaskId = null; } else { // 任务未完成,2秒后再次查询 setTimeout(updatePage, 2000); } } </script> </head> <body> <button onclick="startTask()">Start Task</button> <div id="data"> <!-- 任务完成后显示数据 --> </div> </body> </html>
关键修改说明
- Flask端:
- 新增
/start-task接口,生成唯一任务ID并启动后台线程执行长任务 - 新增
/task-status/<task_id>接口,返回指定任务的完成状态与结果 - 用字典
task_status替代全局变量,支持同时处理多个任务,避免多请求冲突
- 新增
- 前端:
- 移除错误的
Thread调用,改用fetch调用后端API启动任务 - 新增异步轮询逻辑,通过
/task-status接口获取任务状态 - 添加按钮禁用逻辑,防止重复提交任务
- 使用
async/await处理异步请求,代码更简洁可读
- 移除错误的
内容的提问来源于stack exchange,提问作者user366312
相关产品推荐
相关产品推荐

