Javascript事件执行在队列中延迟

时间:2018-02-05 22:16:22

标签: javascript jquery events

我试图解释我的问题,以了解解决问题的更好方法。我搜索了一下,但我不知道如何准确搜索:

  • 我有一个包含三个区域的HTML页面:面板A,网格B和网格C.
  • 在网格C上,我可以对一行(仅点击它)执行操作,更新面板A和网格B上的某些计数器,但它们是根据数据库总计计算的。
  • 当我执行行动时,我立即更新行并触发由面板A和网格B监听的事件,该事件向服务器发送两个请求以更新它的计数器。

每一行更新都有点沉重,如果用户快速点击各行,则javascript执行被锁定,充斥着服务器的面板A和网格B的更新,如果在1或2秒内,可以推迟执行一次事件未被触发。

我会在listenTo回调上解决问题,因为它可能是必须执行事件操作的另一个面板"立即"。

我想象这样的事情(仅在没有事件听过2秒后刷新),但我认为必须有更好的方法:

var eventTimeout = {}; // one for listener
element.bind('eventName' function() {
    if (eventTimeout['eventName']) {
        clearTimeout(eventTimeout['eventName']); // I understand that if the timeout has been exhausted no error is thrown
    }
    eventTimeout['eventName'] = 
        setTimeout(function() {
            eventTimeout['eventName'] = null;
            doAction(); 
        }, 2000);
});

我会放弃这个实现(我还没有测试过),当我有更多时间时,我会把它放在JSFiddle上以帮助理解。

2 个答案:

答案 0 :(得分:1)

你使用你的代码走在正确的轨道上,但你可能想要使用像lodash-throttle函数装饰器这样的东西,而不是在IMO重新发明轮子。

lodash Throttle

  

创建一个限制函数,每个等待毫秒最多只调用一次func。限制函数带有取消方法来取消延迟调用。提供一个options对象,指示应在等待超时的前沿和/或后沿调用func。对限制函数的后续调用将返回最后一次func调用的结果。

来自他们自己网站的例子:

// avoid excessively updating the position while scrolling
jQuery(window).on('scroll', _.throttle(updatePosition, 100));

// invoke `renewToken` when the click event is fired, but not more than once every 5 minutes
jQuery('.interactive').on('click', _.throttle(renewToken, 300000, {
  'trailing': false
}));

// cancel a trailing throttled call
jQuery(window).on('popstate', throttled.cancel);

答案 1 :(得分:0)

使用之前的@bhantol非常有价值的响应以及其他一些stackoverflow响应(https://stackoverflow.com/a/43638411/803195)我已经发布了一个模拟我实际想要的行为的示例代码。

也许它在初始问题上没有明确定义,但我实际上需要使用去抖动它必须是动态的,这取决于一些变量(下面的样本上的复选框)它必须是"延迟"或"立即":

https://codepen.io/mtomas/pen/xYOvBv

var debounced = _.debounce(function() {
  display_info($right_panel);
}, 400);
$("#triggerEvent").click(function() {
  if (!$("#chk-immediate").is(":checked")) {
    debounced();
  } else {
    display_info($right_panel, true);
  }
});

该样本基于在该(有趣)文章上发表的原始样本:

https://css-tricks.com/debouncing-throttling-explained-examples/

- 更新 - 使用lodash的debounce意味着我要输入完整的lodash(72Kb最小化),所以我已经实现了" lite"使用此引用自己辩护:

https://davidwalsh.name/function-debounce

function debounce(func, wait, immediate) {
    var timeout;
    return function() {
        var context = this, args = arguments;
        var later = function() {
            timeout = null;
            if (!immediate) func.apply(context, args);
        };
        var callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
    };
};

我也更新了我的codepen测试。