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

多类函数流式数据输出问题:Flask模板无法显示子函数进度

问题原因

你遇到的核心问题是生成器未被迭代:f2是生成器函数,在f1里直接调用self.f2(i)只会创建一个生成器对象,不会执行f2内部的代码(包括yield语句),所以f2的进度数据根本没被输出。

解决方案

修改f1,遍历f2返回的生成器,把每个进度数据转发出去,这样所有yield的内容都会被Flask的Response作为SSE事件发送给前端:

修改后的Python代码

import time
from flask import Flask, Response

app = Flask(__name__)

class Foo:
    def __init__(self):
        self.bar = 'foobar'

    def f1(self):
        i = 3
        while i != 0:
            # 遍历f2的生成器,转发所有进度数据
            for progress in self.f2(i):
                yield progress
            i -= 1
            
        time.sleep(1)
        yield f'data:{self.bar}\n\n'

    def f2(self, i):
        time.sleep(1)
        yield f'data:{self.bar}{i}\n\n'

@app.route('/process', methods=['GET','POST'])
def process():
    a = Foo()
    return Response(a.f1(), mimetype='text/event-stream')

if __name__ == '__main__':
    app.run(debug=True)

对应调整前端代码

原来的关闭条件是判断e.data == '4',现在要改成判断最终结果'foobar':

$('#process').on('click', e => {
    var source = new EventSource('/process');
    source.onmessage = (e) => {
        $('#result').text(e.data);
        // 收到最终结果时关闭连接
        if (e.data === 'foobar') {
            source.close();
        }
    }
    e.preventDefault();
});
原理说明

生成器函数的特性是:只有当生成器对象被迭代(比如用for循环、next()调用)时,函数内部的代码才会逐步执行,yield语句才会产出数据。所以在f1里必须遍历f2的生成器,把每个产出的进度数据再yield出去,才能让SSE流包含所有进度信息。

内容的提问来源于stack exchange,提问作者teduniq

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:01:25