多类函数流式数据输出问题: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
相关产品推荐
相关产品推荐

