使用 setTimeout 重新加载 Ajax 函数不会首先清除先前的超时

Reloading Ajax function with setTimeout doesnt clear previous timeout first

我正在尝试在单击联系人姓名时加载聊天框。在初始加载时,它会显示收件箱。在我再次尝试单击联系人姓名之前,所有功能都可以正常工作。它加载新的联系人聊天,但也显示原始联系人聊天,即使我设置了 clearTimeout()。

这是JS文件-

$(document).ready(function(){ 
    var contactTimeout;
    var inboxTimeout;

   function contact() {
       var fromName = $('#from').val();
       var toName = $("#to").val();
       $(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
       $(".chat-form").fadeIn(100);

       $.ajax('chat/get-chat.php', {
          data: ({ to: toName,from: fromName}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              contactTimeout = setTimeout(contact, 2000);
          } 
      }); 
   }

   function inbox() {
      var user = $('#from').val();
      $.ajax('chat/get-chat-inbox.php', {
          data: ({ user: user}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              inboxTimeout = setTimeout(inbox, 2000);
           }
       }); 
     }


     // Load inbox when chat box is opened
     $(".chat-arrow").click(function(){
         clearTimeout(contactTimeout);
         inbox();
     });

     // Load chat from contact name
     $(".contact-name").click(function() {
         clearTimeout(contactTimeout); // Here I try and kill previous timeout
         clearTimeout(inboxTimeout);
         var contactName = $(this).attr('id');
         $("#to").val(contactName);
         contact();
     });

});

为什么在点击新的联系人姓名时只添加更多超时功能而不是替换它们?

首先,我建议您不要每次都使用替换,您可以轻松地使用 .html(data) 将新数据放入 chat-body 的现有内容中。

解释是你在 ajax 成功时调用你的函数(服务器响应你的请求需要等待时间),如果你同时点击另一个调用,你将有两个调用而不是一个,因为您无法清除尚未启动的计时器。

解决方案之一是,让计时器仅在其默认状态下工作,当您需要一些快速数据时,您可以呼叫您的联系人而无需调用下一个计时器。

$(document).ready(function(){ 
    var contactTimeout;
    var inboxTimeout;
   
   /* add parameter which will mean will we call timer or not */
   function contact(dotimer) {
       var fromName = $('#from').val();
       var toName = $("#to").val();
       $(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
       $(".chat-form").fadeIn(100);

       $.ajax('chat/get-chat.php', {
          data: ({ to: toName,from: fromName}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              /* default calling of timer with repeating */
              if (dotimer) { contactTimeout = setTimeout(function(){ contact(true); }, 2000); }
          } 
      }); 
   }

   function inbox() {
      var user = $('#from').val();
      $.ajax('chat/get-chat-inbox.php', {
          data: ({ user: user}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              inboxTimeout = setTimeout(inbox, 2000);
           }
       }); 
     }


     // Load inbox when chat box is opened
     $(".chat-arrow").click(function(){
         clearTimeout(contactTimeout);
         inbox();
     });

     // Load chat from contact name
     $(".contact-name").click(function() {
         clearTimeout(inboxTimeout);
         var contactName = $(this).attr('id');
         $("#to").val(contactName);
         /* call function without TIMER, default one will work as it works */
         contact(false);
     });
});