Flask:从生成器以产量流到jQuery/$.post()

Flask:从生成器以产量流到jQuery/$.post(),jquery,json,flask,Jquery,Json,Flask,在我使用jQuery$.post()调用函数后,我想从flask中的生成器流式传输数据块: 我从jQuery调用此函数: $.post("/some/function", {"some": $data}, function(data) { alert(result) }) 这只给了我一个提示,上面写着“result1result2”,而不是每个收益率都有两个单独的提示。因此,在“生成”所有内容后调用回调函数 如何正确地以yield流式传输到jQuery?这是一个AJAX请求,当加载所有

在我使用jQuery$.post()调用函数后,我想从flask中的生成器流式传输数据块:

我从jQuery调用此函数:

$.post("/some/function", {"some": $data}, function(data) {
    alert(result)
})
这只给了我一个提示,上面写着“result1result2”,而不是每个收益率都有两个单独的提示。因此,在“生成”所有内容后调用回调函数


如何正确地以yield流式传输到jQuery?

这是一个AJAX请求,当加载所有数据时,您将处理
警报您无法获得单独的数据块,因为这是一个请求,但可以尝试模拟以下情况:

  • 您可以尝试使用,并从中读取数据,但何时处理此事件是一个非常困难的问题(尤其是对于每个浏览器)

  • 您也可以尝试查看,但浏览器支持存在局限性,对于您的案例来说,这看起来非常困难

  • 别忘了flash等,但对于您的案例来说,它看起来也非常困难

  • 若您的响应很快,那个么您就可以在客户机上获得所有响应和单独的数据(例如,对于二进制对象,您可以使用json和base64,若您知道blob结构,则可以使用blob)

    如果您的响应很长,因为您获得了大数据,并且确实需要块,那么最好提出几个请求,因为新连接的时间比加载大数据块的时间要短。在这种情况下,最好不要对AJAX使用大块,因为它可能引发
    timeout
    异常

    若您的响应很长,因为它需要大量CPU或缓慢的操作,那个么最好启动后台进程(比如
    芹菜
    ),返回响应,并在检查结果后间隔一段时间

    如果您必须以极快的速度获得响应,您可以尝试使用
    websockets
    (在这种情况下,您必须发送不同的消息)

    因此,当流媒体和区块将很有帮助时:

  • 您下载或上载大文件,并希望在flask应用程序中控制速度(用户引用,此操作不使用所有通道)。但是,如果使用例如
    uwsgi
    ,则在执行此操作时,进程或线程将被阻塞
  • 您正在下载或上载大文件,并希望停止/恢复/验证此操作

  • 在这种情况下,可以使用服务器发送的事件。请查看下面的示例:

    from flask import Flask, Response
    import time
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return """
    <!DOCTYPE html>
    <html>
      <head>
        <script>
          if(typeof(EventSource)!=="undefined") {
            var source=new EventSource("/stream");
            source.onmessage=function(event) {
              document.getElementById("result").innerHTML+=event.data + "<br>";
            };
          } else {
            document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
          }
        </script>
      </head>
      <body>
        <h1>Data</h1>
        <div id="result"></div>
      </body>
    </html>
    """
    
    @app.route('/stream', methods=['GET', 'POST'])
    def stream():
        def event_stream():
            n = 0
            while True:
                yield "data: %s\n\n" % n
                n += 1
                time.sleep(1)
        return Response(event_stream(), mimetype='text/event-stream')
    
    if __name__ == '__main__':
        app.run()
    
    来自烧瓶导入烧瓶,响应
    导入时间
    app=烧瓶(名称)
    @应用程序路径(“/”)
    def index():
    返回“”
    if(typeof(EventSource)!=“未定义”){
    var source=neweventsource(“/stream”);
    source.onmessage=函数(事件){
    document.getElementById(“结果”).innerHTML+=event.data+“
    ”; }; }否则{ document.getElementById(“结果”).innerHTML=“对不起,您的浏览器不支持服务器发送的事件…”; } 资料 """ @app.route('/stream',methods=['GET','POST']) def stream(): def event_stream(): n=0 尽管如此: 产生“数据:%s\n\n”%n n+=1 时间。睡眠(1) 返回响应(event_stream(),mimetype='text/event stream') 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app.run()

    服务器发送的事件会阻止开发服务器。要处理多个连接,请使用Gevent

    我想办法是在后台移动长时间运行的进程,将所有内容保存在redis中,让客户端不断更新。Web套接字或类似的东西太过分了:)
    from flask import Flask, Response
    import time
    
    app = Flask(__name__)
    
    @app.route('/')
    def index():
        return """
    <!DOCTYPE html>
    <html>
      <head>
        <script>
          if(typeof(EventSource)!=="undefined") {
            var source=new EventSource("/stream");
            source.onmessage=function(event) {
              document.getElementById("result").innerHTML+=event.data + "<br>";
            };
          } else {
            document.getElementById("result").innerHTML="Sorry, your browser does not support server-sent events...";
          }
        </script>
      </head>
      <body>
        <h1>Data</h1>
        <div id="result"></div>
      </body>
    </html>
    """
    
    @app.route('/stream', methods=['GET', 'POST'])
    def stream():
        def event_stream():
            n = 0
            while True:
                yield "data: %s\n\n" % n
                n += 1
                time.sleep(1)
        return Response(event_stream(), mimetype='text/event-stream')
    
    if __name__ == '__main__':
        app.run()