如何检测页面是否应该更新?

时间:2014-02-19 19:29:32

标签: javascript jquery ajax database http

我在页面中有一个显示摘要数据的表格 这些数据来自摘要数据库表。如果基础表得到更新,我需要刷新页面中显示的这个表 我知道的方法是每隔X秒重新加载页面 但我感兴趣的是在表格实际更新时更新表格 这是什么标准解决方案?我能想到的唯一方法是在表中添加一些额外的列,以便每隔X秒更新一行并且以某种方式“轮询”此列。我认为它可以工作,但它似乎是一个可怕的解决方案,我想知道什么是这个(我认为常见)问题的标准方法。

更新
只是为了添加更多内容。我的问题不是那么通用。我只有1个特定部分的代码更新表,更新完全由我完全控制。它不像是由多个来源更新的表

4 个答案:

答案 0 :(得分:1)

解决这样的问题有很多不同的方法。最好和最有效的解决方案将涉及服务器的一些帮助,以了解何时/发生了什么变化。以下是一些想法:

  1. 使用websocket连接到服务器,以便服务器可以在后端数据发生变化时通知,然后客户端可以请求新数据。

  2. 使用原始页面提供某种“最后一个事务ID”,然后在轮询间隔上使用ajax调用来询问服务器自上次事务ID以来数据是否已更改。如果是,请求新数据。如果没有,没什么可做的。这样可以避免在没有任何实际更改的情况下反复获取数据。

  3. websocket的替代方案是对http push的长轮询,也可以使用它(特别是在不支持websockets的客户端中),以允许服务器在有新数据时通知客户端。

答案 1 :(得分:1)

通讯系统

您有多种方法可以创建一种自动更新的动态页面(例如Facebook)。

  1. 基本。最基本的方法是,就像你说的那样,每X秒轮询一次服务器(拥有一个JavaScript无限的$ .ajax({});每个X调用一个循环秒)查看服务器上是否有新内容。这是一个有效的解决方案,它已被用于过去。

  2. 推送。第二种方式也是long polling or push。如果您在后端使用异步框架(即Node.js,Tornado,Twisted等),您可以非常轻松地使用此解决方案,因为它几乎没有性能成本。对于像PHP或Django这样的其他后端框架,这不是一个很好的方法,因为你为每个请求创建一个进程,直到更新某些内容或者达到Http连接的超时(人们放置了大部分内容)从我看到的那个时间,长时间轮询的30秒计时器)。

  3. 套接字。这是最新且最不受支持的方式。并非所有浏览器都可以访问WebSockets。和以前一样,异步框架更适合这种方法。

  4. 如果您正在使用CGI base back en框架(这意味着WCGI,FastCGI等),如Django,PHP,Flask等,那么您最好采用第一种方法,这是最基本的方法。对您的服务器来说,任何其他的非常资源都是昂贵的。如果你有一个异步后端,那么第二种或第三种方法都可以。 我必须说,Web套接字方法有点难以进入,正确编程并支持框架。

    数据库系统

    选择要用作通信系统的内容后,数据库设计需要反映您需要执行的新查询类型。
    假设用户想要查看自加载页面以来的所有新更改。

    • 这样做的一种简单方法是在每一行上都有一个日期,这是最后一次更改的时间。查询自上次查询时间以来更改的所有行。

    • 更复杂的方法是实施完整的通知系统。对于每个更改或新行,将添加有关它的新通知。您可以在用户和通知之间建立关系以了解他是否已经看过它,并且每24小时安排一个作业来删除旧关系。但很快这一切都变得臃肿。我更喜欢使用NoSQL数据库(JSON,如CouchDB)作为通知系统。您可以轻松更改文档的结构并为所有通知创建特定视图。使用它比使用关系数据库更宽松。如果您想知道用户加载页面后数据是否已更改,您所要做的就是查询通知类型(您要观察更改的数据/表格),并获取创建日期比上次更新的数据/表格。查询时间也没有查看。由于您的表始终反映最后一个状态,因此在页面加载时您会查询表,然后您只查询更改或此处称为通知。

    My Personal Take

    如果你有一个CGI后端,对于一个完整的通知系统,你需要在你的上面添加一个特定的后端结构,用于长轮询或套接字。不要忘记您的客户端还需要有关于如何对新服务器处理程序做出反应的逻辑。为了快速获得结果,如果您的作业指定了这一点,那么您最好只使用页面中的脚本,每1分钟左右重新加载页面。

    如果您已经在使用异步框架,则可以轻松添加通知功能,但需要在数据库上进行繁重的工作,尤其是在通知是关系的情况下。如果你决定专门为此添加一个新的数据库,它还需要你后端的很多app逻辑以及它的训练。

    希望我帮助,欢呼!

答案 2 :(得分:0)

这是WebSockets的前提(http://socket.io用于垫片)。您需要(如前所述)服务器(例如Node.JS)来支持WebSocket功能 - 大多数现代Web浏览器都支持客户端的此API。

Web套接字API(http://www.w3.org/TR/2012/CR-websockets-20120920/)允许浏览器持续地将数据传送到服务器(反之亦然)。

如果更新了数据库记录,您可以设置触发器以将此数据传回客户端。看一下评论板系统(就像我们在StackOverflow上使用的那样) - 例如,由于网上已经有大量的信息,我认为没有必要在这里详细介绍。 / p>

进一步阅读和工具:

正如其他人所提到的,您可以使用AJAX通过setInterval(首选)或setTimeout方法进行轮询。不要忘记创建一个变量来存储集合[Fn]的ID,以防您(或用户)希望取消它:

var pollID = window.setInterval(function poller(){ getAjaxData(); }, 2000);
if (noUpdate) window.clearInterval(pollID);

答案 3 :(得分:0)

轮询是最简单的方法。它看起来像这样:

(function poll() {
  $.ajax('/myTableData', {
    success: function(data) {
        updateTable(data);
    },
    complete: function() {
       setTimeout(poll, 8000); //every eight seconds
    }
  });
})();

然后您将端点/myTableData添加到您的服务器。

Google Docs支持实时协作,在撰写本文时进行了民意调查。然而,更复杂的是民意调查是“漫长的”:它们持续到新数据到达之前,或者经过一定时间(例如40秒),以先到者为准。这减少了轮询量。

或者,您可以查看现代浏览器支持的websockets(IE 10 +)。