plotly.js
Version:
The open source javascript graphing library that powers plotly
102 lines (89 loc) • 2.81 kB
JavaScript
/**
* Copyright 2012-2020, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
;
var timerCache = {};
/**
* Throttle a callback. `callback` executes synchronously only if
* more than `minInterval` milliseconds have already elapsed since the latest
* call (if any). Otherwise we wait until `minInterval` is over and execute the
* last callback received while waiting.
* So the first and last events in a train are always executed (eventually)
* but some of the events in the middle can be dropped.
*
* @param {string} id: an identifier to mark events to throttle together
* @param {number} minInterval: minimum time, in milliseconds, between
* invocations of `callback`
* @param {function} callback: the function to throttle. `callback` itself
* should be a purely synchronous function.
*/
exports.throttle = function throttle(id, minInterval, callback) {
var cache = timerCache[id];
var now = Date.now();
if(!cache) {
/*
* Throw out old items before making a new one, to prevent the cache
* getting overgrown, for example from old plots that have been replaced.
* 1 minute age is arbitrary.
*/
for(var idi in timerCache) {
if(timerCache[idi].ts < now - 60000) {
delete timerCache[idi];
}
}
cache = timerCache[id] = {ts: 0, timer: null};
}
_clearTimeout(cache);
function exec() {
callback();
cache.ts = Date.now();
if(cache.onDone) {
cache.onDone();
cache.onDone = null;
}
}
if(now > cache.ts + minInterval) {
exec();
return;
}
cache.timer = setTimeout(function() {
exec();
cache.timer = null;
}, minInterval);
};
exports.done = function(id) {
var cache = timerCache[id];
if(!cache || !cache.timer) return Promise.resolve();
return new Promise(function(resolve) {
var previousOnDone = cache.onDone;
cache.onDone = function onDone() {
if(previousOnDone) previousOnDone();
resolve();
cache.onDone = null;
};
});
};
/**
* Clear the throttle cache for one or all timers
* @param {optional string} id:
* if provided, clear just this timer
* if omitted, clear all timers (mainly useful for testing)
*/
exports.clear = function(id) {
if(id) {
_clearTimeout(timerCache[id]);
delete timerCache[id];
} else {
for(var idi in timerCache) exports.clear(idi);
}
};
function _clearTimeout(cache) {
if(cache && cache.timer !== null) {
clearTimeout(cache.timer);
cache.timer = null;
}
}