2013-06-18 124 views
7

發生器流將jQuery/$交()我想的流數據的數據塊從在燒瓶內的發電機後我稱爲與jQuery $ .POST()函數:燒瓶中:從與產量

@app.route('/some/function', methods=['POST']) 
def calculateSomething(): 
    def g():   
     # do something here 
     yield 'result1' 
     # do more ...     
     yield 'result2'  
    return Response(g()) 

我調用這個函數從jQuery的:

$.post("/some/function", {"some": $data}, function(data) { 
    alert(result) 
}) 

這只是給了我一個警告說「result1result2」和每個產量沒有兩個獨立的警報。因此,在所有事情都被「取消」之後調用回調函數。

我怎樣才能正確地流向jQuery的收益?

回答

3

這是一個AJAX請求,您將在加載所有數據時處理alert你不能單獨的塊,因爲它是一個請求,但可以嘗試效仿這一:

  1. 您可以嘗試使用XMLHttpRequest2.progress eventProgressEvent.loadedXMLHttpRequest2.response讀取數據,但是當這種事件將被真的很難處理問題(特別是對於每個瀏覽器)。

  2. 你也可以試試看WebRTC,但是這對瀏覽器的支持有一定的限制,對你的情況來說看起來很不合理。

  3. 不要忘了flash等,但它也看起來像你的情況不合理的困難。

如果你的反應快,那麼你可以得到客戶的所有反應和獨立的數據(例如,你可以使用JSON使用Base64二進制對象或斑點,如果你知道BLOB結構)。

如果您的迴應很長,因爲您獲得大數據並且您確實需要塊,那麼最好提出幾個請求,因爲新連接的時間會少於大塊加載。在這種情況下,最好不要在AJAX中使用大塊,因爲它可能會拋出timeout異常。

如果您的響應時間太長,因爲它佔用CPU太多或運行速度較慢,那麼最好啓動後臺進程(如celery),返回響應並在一定間隔後檢查結果。

如果您必須獲得非常快的響應,您可以嘗試使用web sockets(在這種情況下,您必須發送不同的消息)。

所以流時及碎塊會有所幫助:

  1. 您上傳或下載大型檔案,並希望在燒瓶應用控制速度(用戶報價,請不要使用該操作的所有信道)。但是,如果您使用例如uwsgi您的進程或線程將在此操作處理時被阻止。
  2. 您正在下載或上傳大文件並希望停止/恢復/驗證此操作。
+0

我想要走的路是在後臺移動長時間運行的進程,將所有內容保存在redis中並讓客戶端不斷更新。網絡套接字或類似的東西是矯枉過正:) –

6

在這種情況下,您可以使用服務器發送的事件。請看下面的示例:

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() 

服務器發送的事件會阻塞您的開發服務器。使用Gevent處理多個連接。 http://flask.pocoo.org/docs/deploying/others/#gevent