奇怪的setTimeout行为Javascript

时间:2013-10-09 20:07:24

标签: javascript ajax settimeout

以下脚本应该执行以下操作:

在页面加载时,它会将超时设置为20秒,然后将在ajax调用中自动更新所需内容。 如果用户单击一个表示RELOAD的按钮,它将调用函数reloadContent(),从而清除超时并再次设置一个。

所以基本上,如果用户手动重新加载,它将重新启动超时,以避免过于接近的呼叫。

它工作一半,因为计时器似乎被重置,但reloadContentTimeout()将在手动加载动作10秒后执行,这是超时时间的一半。

我做错了吗?

谢谢!

  /**
   *  Reload content
   */
  function reloadContent(elementId) {
    $(elementId).load(window.location.href+' '+elementId+' > *');
    clearTimeout(timeoutId);
    reloadContentTimeout(false);
  }

  /**
   * Reload content every X seconds (20)
   */
  var timeoutId;
  function reloadContentTimeout(now)
  {
    now = (typeof now === 'undefined' ? true : now);
    if( now ) {
      reloadContent('#table-content');
    }
    timeoutId = setTimeout(reloadContentTimeout, 1000 * 20);
  }
  reloadContentTimeout(false);

2 个答案:

答案 0 :(得分:3)

因为您拨打reloadContentTimeout两次,会重新分配timeoutId。其中一个ID没有被清除,事件的触发频率超出预期。让我们展开你的调用堆栈:

if (now) {
    $(elementId).load();
    clearTimeout(timeoutId);
    // this reassigns timeoutId
    reloadContentTimeout(false)
}
// this is where timeoutId is assigned.  It gets assigned
// by this call, but also the call above.
timeoutId = setTimeout(reloadContentTimeout, 1000 * 20);

我会切入追逐:这将解决问题。

if (now) {
    /* snip */
}
else {
    timeoutId = /* snip */
}

答案 1 :(得分:1)

请检查您的通话顺序

  • 每次调用reloadContentTimeout都会启动一个新的超时(对于两个可能的参数值“undefined”和“false”)
  • 20秒后你重新加载内容,这将在清除旧内容后开始一个新的超时(这是非常无用的,因为计时器已经被激活)。然后你开始另一个超时并重新分配timeoutId而不清除你之前创建的那个。现在你有两个超时运行,每次超时后都会不断发生

检查@Explosion Pills的答案。它将帮助您解决问题