You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Flask+JavaScript长任务完成后异步更新网页的代码?

修复Flask+JS异步长任务页面更新问题

原代码核心问题

  • Flask端缺少启动长任务和查询任务状态的API接口,前端无法触发后端任务也没法获取任务进度
  • 前端错误使用浏览器不存在的Thread API,浏览器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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:40:17