防止在单击事件中重复调用异步加载函数

Preventing a async load function from being called repetitively in a click event

本文关键字:调用 异步 加载 函数 单击 事件      更新时间:2023-09-26

我有一个回调函数,它一次加载一页数据。单击上一个和下一个链接时会调用/触发该函数。当最终用户快速点击下一个链接并重复调用加载函数时,我遇到了动画和加载及时完成的问题。我知道这是一个异步调用,但有没有办法对加载/动画进行排队或暂停,以便在另一个加载完成之前,一个加载不运行?

  function NextPageNav_Click() {
      var CurPage = parseInt($('#CurPage').attr('value').toString()) + 1;
      $('#CurPage').attr('value', CurPage);
      loadPage(CurPage, 'Next');
  }

  function loadPage(CurPage, State) {
      $.ajax({
          type: "POST",
          url: "defaulttmp3.aspx/GetLatestProfiles",
          cache: true,
          async: false,
          data: "{'PageIndex': " + CurPage + "}",
          contentType: "application/json; charset=utf-8",
          dataType: "json",
          success: function (msg) {

              switch (State) {
                  case 'Previous':
                      $('<div id="nextitems"></div>').insertBefore('#curitems');
                      $('#nextitems').empty();
                      $('#nextitems').setTemplateURL('page/public/templates/profiletemplate.htm');
                      $('#nextitems').processTemplate(msg);
                      $('#items').attr('style', 'left:-920px');
                      $('#items').animate({
                          "left": "+=920px"
                      }, 500, function () {
                          $('#curitems').remove();
                          $('#nextitems').attr('id', 'curitems');
                      }
                      );
                      break;
                  case 'Next':
                      $('<div id="nextitems"></div>').insertAfter('#curitems');
                      $('#nextitems').empty();
                      $('#nextitems').setTemplateURL('page/public/templates/profiletemplate.htm');
                      $('#nextitems').processTemplate(msg);
                      $('#items').animate({
                          "left": "-=920px"
                      }, 500, function () {
                         $('#curitems').remove();
                         $('#nextitems').attr('id', 'curitems');
                         $('#items').attr('style', 'left:0');
                      }
                      );
                   break;  
                  default:
                      $('#curitems').empty();
                      $('#curitems').setTemplateURL('page/public/templates/profiletemplate.htm');
                      $('#curitems').processTemplate(msg);
                      break;
              }

              var RowsReturned = parseInt(msg.d.RowsReturned.toString());
              var PageSize = parseInt(msg.d.PageSize.toString());
              initPrevNextLinks(RowsReturned, PageSize, CurPage);

          },
          error: function (request, status, error) {
              alert(request.statusText);
          }
      });
  }

相反,请尝试限制点击

var throttleAsync(callback, time) {
     var timeoutId = null;
     return function() {
           clearTimeout(timeoutId);
           timoeoutId = setTimeout(callback, time || 1);
     };
}

编辑

之前的每次调用都会重置它,但是要使用第一次点击&忽略后续点击

var throttleAsync(callback, time) {
     var timeoutId = null;
     return function() {
           if(timeoutId == null) {
                timoeoutId = setTimeout(function() { timeoutId = null; callback; }, time || 1);
           }
     };
}

如果你想在开始下一个动画之前停止上一个动画,你可以使用.stop()jQuery函数这样做:

$('#items').stop(true, true).animate(...);

.stop()的选项控制停止的动画会发生什么,但如果您只是希望它跳到最后并完成,则可能需要.stop(true, true)

在您的特定情况下,您可能还需要担心排队的ajax调用,这些调用可能在下一次单击之前尚未完成。在这种情况下,您可以保留一个关于ajax调用是否正在运行的标志,然后忽略任何点击,也可以尝试使用.abort()中止当前正在运行的ajax调用,如图所示。

我可能建议在ajax调用已经在进行时忽略任何按钮按下,因为更快地得到结果可能没有那么有用。