2017-06-01 98 views
3

我有一個Google App Engine應用程序,使用webapp2框架,與MySQL數據庫交互。應用程序的用戶可以上傳數據。在上傳過程中,我想顯示一個進度條,因爲這可能需要幾分鐘的時間。
基於我在其他主題中看到的(主要是:this topicthis one),我正在研究一種JSON/Javascript解決方案,這對我來說都是新的。基於腳本進度的動態進度條?

如果我傳遞一個隨機數,進度條本身正在工作。但是,我無法弄清楚如何從Python腳本中「加載」更改的值。

這裏的HTML/CSS/JavaScript的:

HTML: 
<div id="myProgress"> 
    <div id="myBar"</div> 
</div> 

CSS: 
#myProgress {width: 300px; 
height: 30px; 
background-color: #ddd; 
} 
#myBar {width: 1%; 
height: 30px; 
background-color: #4CAF50; 
} 

Javascript:  
<script type="text/javascript"> 
function move() { 
    var elem = document.getElementById("myBar"); 
    var width = 1; 
    var id = setInterval(frame, 1000); 
    function frame() { 
     if (width >= 100) { 
      clearInterval(id); 
     } 
     else { 
      //var randomnumber = Math.floor(Math.random() * 100); --> works 
      var randomnumber = function update_values() { 
       $SCRIPT_ROOT = {{ script_root }}; 
       $.getJSON($SCRIPT_ROOT+"/uploading", 
        function(data) { 
         $("#width").text(data.width+" %") 
        }); 
      } ; --> this is wrong I assume 
      var width = randomnumber; 
      elem.style.width = width + '%'; 
     } 
    } 
} 
window.onload=move(); 
</script> 

的進步來自於對Python中環路嵌入在加載頁面的腳本。腳本完成一個活動後,我希望將計數器的結果作爲寬度傳遞給進度條。使用靜態變量,我使用常規Jinja方式。

class UploadingpageHandler(webapp2.RequestHandler): 
def get(self): 
    activities_list = [1,2,3,4,5,6,7,8,9,10] 
    counter = 0 
    script_root = 'localhost:10080' 

    for activity in activities_list: 
     counter = counter + 10 
     upload.do_stuff_in_some_function_with_MySQL() 
     obj = { 
     'width': counter 
     } 
     self.response.headers['Content-Type'] = 'application/json' --> this 
     self.response.out.write(json.dumps(obj)) --> and this is wrong I assume 

    template_vars = { 
    'script_root': script_root 
    } 
    template = jinja_environment.get_template('uploading.html') 
    self.response.out.write(template.render(template_vars)) 

如何更改腳本以使其工作?或者有更好的方法來解決這個問題嗎?

+0

一個簡單的ajax與進度條上傳... https://stackoverflow.com/questions/26674575/php-upload-extract-and-progressbar/26679480#26679480這個例子發佈到PHP,但有一些改動我'我確定它會爲你工作。 – NewToJS

+0

感謝您的回覆。我仍然不知道如何改變建議的解決方案,但是......你能指導我更多地瞭解哪些部分需要改變以在JavaScript中獲得正確的變量嗎?我也在尋找一種方法來加載Python腳本中的值。 – Pieter

+0

如果你上傳的東西你不需要讓python傳遞任何東西,只要讓它處理上傳,我已經添加了事件監聽器來監聽上傳過程。所以'runprogress(event)'將計算0-100的過程,所以如果你添加console.log(百分比),你會看到它的日誌0到100.'uploadcomplete(event)'將在上傳完成後執行,所以你可以使用它來設置狀態消息並清除/重置進度條。至於對ajax文章的更改,您應該可以將'upload.php'更改爲您要使用的服務器端文件。 – NewToJS

回答

1

您需要將「活動」的進度存儲在某個地方的功能之外。

hacky的「解決方案」是將其存儲到某種緩存解決方案中,例如memcached或redis以及某種時間戳/簽名,以便您可以檢索它(並使用cron作業類型的東西使舊條目無效)。

或者您可以將球取出並使您的任務完全異步,如Celery,但我懷疑您可以在Google App Engine上做到這一點。

+1

謝謝!我想我以前曾嘗試芹菜。如果我沒有記錯,它不適用於GAE。GAE確實有自己的任務隊列(https://cloud.google.com/appengine/docs/standard/python/taskqueue/)。這是否也一樣?我會研究memcached和redis以及如果不是... – Pieter

+0

GAE任務隊列似乎正是你所需要的。由於這是一系列要求,我認爲最好的解決方案確實是任務隊列,但是開發這是一項漫長的工作。我會根據進度條的實際需要權衡開發成本。這是您網站的主要組成部分嗎?如果是這樣,處理這些任務(包括重試等)是關鍵。如果不是的話,那麼也許應該重新思考你想要從新的方法中做什麼,或者完全放棄進度條。 –

+0

其中一種新穎的方法是將10個任務(或稱爲他們所稱的活動)分解爲10個獨立的入口點,然後在客戶端處理這些任務的「調度」,而不是像當前那樣,這是Python函數中的一個循環。基本上,一旦任務1完成(可以通過對ajax請求的回調觸發的事件),啓動任務2.通過這種方式,您可以在JS代碼中交易開發Python任務隊列系統的複雜性的代價(您可能失去一些功能,如重試任務) –