【问题标题】:Chat application polling聊天应用轮询
【发布时间】:2013-08-14 06:34:45
【问题描述】:

我正在开发一个聊天应用程序,它会在超时时轮询服务器。 如果随着时间的推移,最近没有任何活动,超时会增加。 函数loadNew() 对服务器执行ajax 调用,服务器以消息数据进行响应。

pollTimeoutTime = 500;
function poll() {
    pollTimeout = setTimeout(function(){
        loadNew();
        if (!new_messages_count) {
            //Increasing delay between polls as no messages are incoming to a maximum of 1 minute/60 seconds
            if (pollTimeoutTime < 60000) pollTimeoutTime = pollTimeoutTime * 1.25;
        } 
        else {
            //Reset delay between poll to default of 0.5 seconds
            pollTimeoutTime = 500;
        }
        poll();
    },pollTimeoutTime);
}

我遇到的问题是超时函数不等待函数 loadNew() 完成,如果超时时间低于 ajax 所需的时间,这会导致相同的轮询被发送两次或更多次调用函数完成。 因此,服务器会多次响应相同的数据,这会导致聊天中的消息重复显示。

有没有办法让超时仅在loadNew() 完成获取和显示数据后触发?

编辑: 使用@Brad M 的答案后,它不再重复消息。我仍然希望有一种方法可以在用户提交消息后进行投票,以便立即显示新消息。这会干扰loadNew() 中设置的超时,从而导致消息再次重复。你能想出一种方法来让它发挥作用吗?

【问题讨论】:

  • 你明白setTimeout是在指定延迟后运行函数,而不是在一定时间后停止函数吗?
  • 是的,但是我读到超时只是在功能完成后才开始,似乎不是这样..
  • 不,这不是发生的事情。 setTimeout 只是在第二个参数指定的时间之后执行第一个参数。 developer.mozilla.org/en-US/docs/Web/API/window.setTimeout

标签: javascript jquery ajax timeout


【解决方案1】:

没有看到您的 loadNew 函数,一个简单的解决方法可能是更改该函数以返回您的 ajax 调用 (return $.ajax({...});) 并更改您发布到此的代码:

pollTimeoutTime = 500;
function poll() {
    pollTimeout = setTimeout(function () {
        loadNew().done(function (result) {
            if (!new_messages_count) {
                //Increasing delay between polls as no messages are incoming to a maximum of 1 minute/60 seconds
                if (pollTimeoutTime < 60000) pollTimeoutTime = pollTimeoutTime * 1.25;
            } else {
                //Reset delay between poll to default of 0.5 seconds
                pollTimeoutTime = 500;
            }
            poll();
        });
    }, pollTimeoutTime);
}

【讨论】:

    【解决方案2】:

    使用 successcomplete 等 ajax 回调函数来触发新的轮询。

    【讨论】:

    • 我也想过,不知道如何实现,但我会立即尝试。我会告诉你它是否有效。
    • 这是否可行是毫无疑问的;这只是逻辑。 ajax回调函数的逻辑是xhr对象的readystate发生变化后执行的东西。
    • 有没有办法在不干扰设置超时的情况下调用 loadNew()? (见编辑过的问题)
    • 您正在深入研究非常深刻的概念。有很多解决方案,但最好的方法是只显示用户立即输入的消息,然后在下次轮询数据库后,验证/调整消息的顺序。 (即添加消息时无需轮询数据库)
    • 谢谢,我会让服务器返回新消息的插入ID,以便下次投票时可以省略。
    猜你喜欢
    • 2010-09-07
    • 2012-11-06
    • 1970-01-01
    • 2013-03-28
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多