user2387226
user2387226

Reputation:

Throttle function for 2 seconds

I have the following function that displays download information such as file size and speed. The information seems to get updated several times a second. I would like to only have the progressInfo section updated every 2 seconds to keep the displayed information from jittering.

I've already tried using timeouts and intervals, but can't seem to get this to work.

https.get(options, function (update) {
    update.on('data', function (chunk) {
        file.write(chunk);
        len += chunk.length;
        fileDownloaded = (len / 1048576).toFixed(1);
        now = Date.now(); speed = len / (now - startTime) / 1024;
        speed = ' - ' + speed.toFixed(1) + ' MB/s';

        setInterval(function() {
            progressInfo.html(fileDownloaded + ' MB of ' + speed);
        }, 2000);
    });
});

Upvotes: 2

Views: 688

Answers (2)

Paul Wasilewski
Paul Wasilewski

Reputation: 10372

Just prevent the repeated function call after a function is already called. You can use a simple flag to check if the html should be updated or a processInfo update is already started.

And use setTimeout(function, milliseconds) instead of setIntervall(function, milliseconds) to execute the update of processInfo function only ones.

Upvotes: 0

jmancherje
jmancherje

Reputation: 6633

Try using a throttle function from lodash or underscore.

from the underscore documentation:

throttle

_.throttle(function, wait, [options]) 

Creates and returns a new, throttled version of the passed function, that, when invoked repeatedly, will only actually call the original function at most once per every wait milliseconds. Useful for rate-limiting events that occur faster than you can keep up with.

function updateProgress(fileDownloaded, speed) {
    progressInfo.html(fileDownloaded + ' MB of ' + speed);
}

function throttledProgress = _.throttle(updateProgress, 2000);

https.get(options, function (update) {
    update.on('data', function (chunk) {
        file.write(chunk);
        len += chunk.length;
        fileDownloaded = (len / 1048576).toFixed(1);
        now = Date.now(); speed = len / (now - startTime) / 1024;
        speed = ' - ' + speed.toFixed(1) + ' MB/s';
        // invoked the throttled function here
        throttledProgress(fileDownloaded, speed)
    });
});

If you don't want to add a whole external library to handle this one case here's a simple implimentation of a throttling function

var throttle = function(func, wait) {
  var timer;
  return function(){
    var currTime = new Date();
    var elapsed = currTime - timer;
    if (timer === undefined || elapsed > wait){
      func.apply(this, arguments);
      timer = currTime;
    }
  };
};

Upvotes: 2

Related Questions