长时间的网络请求进度条

3
在我正在开发的Django应用程序中,我刚刚添加了将多个文件(总共50MB起步)归档到zip文件的功能。目前,我是这样做的:
get files to zip
zip all files
send HTML response

显然,这会导致第二行出现长时间等待,因为文件正在被压缩。我能做什么来让用户体验更好?虽然进度条是最好的解决方案,但即使只返回一个静态页面说“请稍等”或其他内容也可以改善用户体验。欢迎提出您的想法和建议。
4个回答

4

需要注意的是,显示进度条可能并不是一个好主意,因为您可能会遇到超时或者由于同时提交了大量请求而使服务器受损。

将压缩任务放入队列中,并通过回调方式通知用户 - 例如通过电子邮件 - 进程已经完成。

请查看django-lineup

您的代码将如下所示:

from lineup import registry
from lineup import _debug

def create_archive(queue_id, queue):
    queue.set_param("zip_link", _create_archive(resource = queue.context_object, user = queue.user))
    return queue


def create_archive_callback(queue_id, queue):
    _send_email_notification(subject = queue.get_param("zip_link"), user = queue.user)
    return queue

registry.register_job('create_archive', create_archive, callback = create_archive_callback)

在您的视图中,通过以下方式创建排队任务:
    from lineup.factory import JobFactory
    j = JobFactory()
    j.create_job(self, 'create_archive', request.user, your_resource_object_containing_files_to_zip, { 'extra_param': 'value' })

然后运行您的队列处理程序(可能在屏幕会话中):

./manage.py run_queue

噢,关于这个话题,你可能也会对估算zip文件的创建时间感兴趣。我在那里得到了非常流畅的答案。


2

0

您可以使用“日志文件”来跟踪压缩文件以及剩余的文件数量。

程序化的方式应该是这样的:

  1. 计算文件数量,将其以totalfiles.filespreocessed的格式写入文本文件中
  2. 每次压缩一个文件,就更新该文件

因此,如果您需要压缩3个文件,则日志文件将增长为:

3.0 -> begin, no file still processed
3.1 -> 1 file on 3 processed, 33% task complete
3.2 -> 2 file on 3 processed, 66% task complete
3.3 -> 3 file on 3 processed, 100% task complete

然后使用一个简单的ajax函数(间隔)每秒钟检查一次日志文件。

在Python中,打开、读取和写入这样小的文件应该非常快,但如果您有许多用户同时执行此操作,则可能会导致一些请求问题,但显然您需要为每个请求创建一个日志文件,可能是随机名称,并在任务完成后删除它。

一个问题可能是,为了让ajax读取日志文件,您需要每次更新它时在Python中打开和关闭文件处理程序。

最后,为了获得更准确的进度条,您甚至可以使用文件大小而不是文件数量作为参数。


-1

比静态页面更好的是,使用Shadowbox、JQuery UI或一些自定义方法显示JavaScript对话框,并带有一个加载指示器(您可以在hxxp://www.ajaxload.info/上获取一些)。您也可以在页面中显示加载指示器,而无需对话框。大多数用户只想知道他们的操作正在处理中,并且可以在没有可靠进度信息的情况下继续进行(“请稍等,这可能需要一些时间...”)

JQuery UI还具有进度条API。您可以定期向网站上的专用页面发出AJAX查询,以获取进度报告并相应地更改进度条。根据归档运行的频率、可以触发它的用户数量以及如何验证您的用户,这可能会相当困难。


好的...那么这就是我制作进度条的方式。但在开始压缩文件之前,我该如何让它真正输出HTML呢? - Josh Hunt
使用AJAX完成整个任务。将任务跟踪在会话中,这样如果用户导航离开页面,您可以重新创建回调和状态指示器。 - annakata
确实。您可以使用jQuery.post()或jQuery.get()来进行AJAX请求,检索所需内容并更新状态。如果您想要轻松解析响应,请使用JSON对象(只需eval()检索到的数据,您就有了一个常规的Javascript对象)。它可以包含百分比以及正在运行操作的文本描述。 - Xr.
但是我该如何返回HTML,然后继续归档文件呢? - Josh Hunt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接