2

I'm trying to explain my problem to know the better way to solve it. I've searching a bit, but I don't know how to search exactly:

  • I have an HTML page with three areas: Panel A, Grid B and Grid C.
  • On grid C, I can do an action on a row (only clicking it) that updates some counters on panel A and Grid B, but they're calculated on database totals.
  • When I do the row action I update the row immediately and trigger an event listened by Panel A and Grid B which sends both requests against the server to update it's counters.

Every row update is a bit heavy and if the user clicks various rows fast, the javascript execution is locked flooding the server with updates of Panel A and Grid B which could be deferred to execute only one time if on 1 or 2 seconds the event is not triggered.

I would solve the problem on the listenTo callback because it could be another panel that the event action must be performed "immediately".

I imagine something like this (only refresh after 2 seconds of no event listened), but I think that there must be a better way:

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); }); 

I'll go away with that implementation (I haven't tested yet), when I have more time, I'll put it on a JSFiddle to help to understand.

2 Answers 2

1

You are on the right track with your code but you may want to use something like lodash-throttle function decorators rather than reinventing the wheel here IMO.

lodash Throttle

Creates a throttled function that only invokes func at most once per every wait milliseconds. The throttled function comes with a cancel method to cancel delayed invocations. Provide an options object to indicate that func should be invoked on the leading and/or trailing edge of the wait timeout. Subsequent calls to the throttled function return the result of the last func call.

examples from their own site:

// 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); 
Sign up to request clarification or add additional context in comments.

1 Comment

Ohh! It's just what I want! Thanks!
0

Using the previous @bhantol very valuable response, and some other stackoverflow responses (https://stackoverflow.com/a/43638411/803195) I've published a sample code that simulates the behavior I actually want.

Perhaps it was not well defined on initial question, but I need actually use debounce and it must be dynamic, depending on some variables (a checkbox on the following sample) it must be "delayed" or "immediate":

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); } }); 

The sample is based on a original sample published on that (interesting) article:

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

-- UPDATE -- Using debounce of lodash implies me to import full lodash (72Kb minimized), so I've implemented a "lite" own debounce using this reference:

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); }; }; 

I've updated my codepen test too.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.