如何快速刷新HTML元素?

时间:2014-05-31 04:29:43

标签: javascript python google-app-engine

我确定我在这里做了一些愚蠢的事,但我只是想学习套接字/通道,以便将内容从服务器动态推送到客户端。这是我的服务器端代码,它每秒推送一次随机值:

import datetime
import webapp2
import jinja2
import os
import json
import logging
from google.appengine.api import channel
import random
import time
template_env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.getcwd()))

timestamp = unicode(datetime.datetime.now())
class MainPage(webapp2.RequestHandler):
    def get(self):
        if self.request.get('query'):
        # request to get data
            while True:
                random_num = random.randrange(80,90)
                logging.info(random_num)
                channel.send_message(timestamp,str(random_num))
                time.sleep(1)

        token = channel.create_channel(timestamp)
        context = {
            'token': token, 
        }
        template = template_env.get_template('home.html')
        self.response.out.write(template.render(context))
application = webapp2.WSGIApplication([('/', MainPage)],debug=True)

这是我的HTML / javascript:

<script type="text/javascript" src="/_ah/channel/jsapi"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<body>
    <button type="button" onclick="createConnection()">Create Connection</button>
    <button type="button" onclick="startStream()">Start Data Stream</button>
    <div id="connectionalive"></div>
    <div id="value"></div>
<script>
function createConnection() {
    channel = new goog.appengine.Channel('{{ token }}');
    socket = channel.open();
    //socket.onopen = onOpened;
    socket.onmessage = displayData;
    //socket.onerror = onError;
    //socket.onclose = onClose;
    parseResponse()
}
function displayData(msg) {
    console.log("received message"); 
    $("#value").html("<p style='font-family: Helvetica, sans-serif; color: red; font-size: 26px;'>"+msg.data+"</p>");
    }
function parseResponse() { 
        $("#connectionalive").html("<p style='font-family: Helvetica, sans-serif; color: black; font-size: 14px;'>Connection Alive</p>");
        }
function startStream() { 

    $.ajax('/', {
        type: 'GET',
        async: false,
        data: {
        query: 'startstream',
    }, 
    success: function() { logging.info("stream started") }
}); 

} 
</script>
</body>

代码很粗糙,我只是试图看到我可以每秒发送一次新值并在我的网站上更新。但是,当我点击&#34;开始数据流&#34;时,我的浏览器挂起,而看起来我的后端服务器正在通过该频道发送数据,浏览器不会更新div。当我停止while循环时,浏览器会更新,但只是一次......它不会像我预期的那样显示每秒更新的值流。我有什么东西在这里失踪吗?谢谢。

1 个答案:

答案 0 :(得分:1)

我在你发布的代码中没有看到while循环,但是如果你正在使用来自浏览器的同步ajax调用进行while循环,那么你永远不会给浏览器重新绘制的机会。

更好的实现是将ajax调用配置为异步,启动ajax调用,然后在完成时(例如调用完成处理程序),您可以更新页面并触发下一个ajax调用。然后,该页面将在异步ajax调用期间更新。

繁忙的循环和同步的ajax调用都是浏览器中的坏事。浏览器必须回到自己的事件循环,以便重新绘制,响应事件并做其他事情以保持浏览器的响应。代码通常在浏览器中使用setTimeout()setInterval()重复,这使您可以安排一些代码在未来运行几毫秒,在此之前的时间内,浏览器可以处理它。自己的家务(重绘,事件处理等)。在您的情况下,您可以通过异步ajax调用获得自然的计时节奏。启动异步ajax调用,返回事件循环,以便浏览器可以进行处理。然后,当为ajax调用触发完成函数时,处理结果并开始下一个ajax调用。