1

经过一个晚上的浏览和尝试,我有一些工作,但我想知道这是否都是正确的,或者可以改进。我问,因为我不经常使用 javascript 或 jquery/ajax....

在 django 应用程序中,我有一个 celery 任务正在运行,我想在任务完成后用结果更新浏览器。

为此,我使用 setTimeout 创建了一个 javascript 计时器(因此我可以在成功时停止它)。

现在我希望能够支持多个计时器;我要更新的每个字段(或任务)一个;我不确定如何在匿名函数上设置新的超时,所以我给它起了一个名字并使它成为全局的;那是对的吗?有没有更好的方法来做到这一点?

保罗·博尔曼斯

{% block jscript %}
<script>
function updateTaskResult(i, e) {
$.ajax({
  type: "GET",
  url: "{% url 'task_status' %}",
  cache: false,
  data: {task_id: e.id},
  context: e
}).done(function(json) {
    $(e).html("state=" + json.state + " result=" + json.result);
    if(json.state !== "{{ success }}") {
        setTimeout(updateTaskResult, 1000, i, e);
    }
});
}

$("div.status").each(function(i, e) {
    updateTaskResult(i,e);
});
</script>
{% endblock %}
4

2 回答 2

1

为了避免全局变量,您可以将代码包装在立即运行的匿名函数中。这会创建一个私有变量范围供您使用。

此外,由于您不在 AJAX 回调中使用关键字this,因此无需将上下文设置为e

<script>
    (function() {
        var updateTaskResult = function (i, e) {
            $.ajax({
                type: "GET",
                url: "{% url 'task_status' %}",
                cache: false,
                data: {task_id: e.id},
            }).done(function(json) {
                $(e).html("state=" + json.state + " result=" + json.result);

                if(json.state !== "{{ success }}") {
                    setTimeout(updateTaskResult, 1000, i, e);
                }
            });
        }

        $("div.status").each(function(i, e) {
            updateTaskResult(i,e);
        });
    })();
</script>

匿名函数可以与 setTimeout 一起使用,如下所示:

<script>
    setTimeout(function () {
        // Do stuff.
    }, 1000);
</script>
于 2012-11-14T22:07:21.693 回答
0

您必须意识到这是对资源的浪费。这不是正确的做法。您要做的是实施PUSH.

对于 django,请查看 evserver,“轻量级异步 Python WSGI 服务器”。看起来很有希望。另外,检查diesel.io。这样,只有当有一些数据要推送时,您的服务器才会将数据推送到浏览器中(您不需要从客户端检查 t )。

如果你使用 celery,我想你不害怕修补 python,所以要正确。

于 2012-11-15T00:01:50.903 回答