基于脚本进度的动态进度条?

问题描述:

我有一个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://*.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

您需要将“活动”的进度存储在某个地方的功能之外。

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任务队列系统的复杂性的代价(您可能失去一些功能,如重试任务) –