artdaq_node_server  v1_00_08
 All Classes Namespaces Files Variables Pages
debounce.js
1 var isObject = require('./isObject'),
2  now = require('./now'),
3  toNumber = require('./toNumber');
4 
6 var FUNC_ERROR_TEXT = 'Expected a function';
7 
8 /* Built-in method references for those with the same name as other `lodash` methods. */
9 var nativeMax = Math.max,
10  nativeMin = Math.min;
11 
66 function debounce(func, wait, options) {
67  var lastArgs,
68  lastThis,
69  maxWait,
70  result,
71  timerId,
72  lastCallTime,
73  lastInvokeTime = 0,
74  leading = false,
75  maxing = false,
76  trailing = true;
77 
78  if (typeof func != 'function') {
79  throw new TypeError(FUNC_ERROR_TEXT);
80  }
81  wait = toNumber(wait) || 0;
82  if (isObject(options)) {
83  leading = !!options.leading;
84  maxing = 'maxWait' in options;
85  maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
86  trailing = 'trailing' in options ? !!options.trailing : trailing;
87  }
88 
89  function invokeFunc(time) {
90  var args = lastArgs,
91  thisArg = lastThis;
92 
93  lastArgs = lastThis = undefined;
94  lastInvokeTime = time;
95  result = func.apply(thisArg, args);
96  return result;
97  }
98 
99  function leadingEdge(time) {
100  // Reset any `maxWait` timer.
101  lastInvokeTime = time;
102  // Start the timer for the trailing edge.
103  timerId = setTimeout(timerExpired, wait);
104  // Invoke the leading edge.
105  return leading ? invokeFunc(time) : result;
106  }
107 
108  function remainingWait(time) {
109  var timeSinceLastCall = time - lastCallTime,
110  timeSinceLastInvoke = time - lastInvokeTime,
111  result = wait - timeSinceLastCall;
112 
113  return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
114  }
115 
116  function shouldInvoke(time) {
117  var timeSinceLastCall = time - lastCallTime,
118  timeSinceLastInvoke = time - lastInvokeTime;
119 
120  // Either this is the first call, activity has stopped and we're at the
121  // trailing edge, the system time has gone backwards and we're treating
122  // it as the trailing edge, or we've hit the `maxWait` limit.
123  return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
124  (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
125  }
126 
127  function timerExpired() {
128  var time = now();
129  if (shouldInvoke(time)) {
130  return trailingEdge(time);
131  }
132  // Restart the timer.
133  timerId = setTimeout(timerExpired, remainingWait(time));
134  }
135 
136  function trailingEdge(time) {
137  timerId = undefined;
138 
139  // Only invoke if we have `lastArgs` which means `func` has been
140  // debounced at least once.
141  if (trailing && lastArgs) {
142  return invokeFunc(time);
143  }
144  lastArgs = lastThis = undefined;
145  return result;
146  }
147 
148  function cancel() {
149  if (timerId !== undefined) {
150  clearTimeout(timerId);
151  }
152  lastInvokeTime = 0;
153  lastArgs = lastCallTime = lastThis = timerId = undefined;
154  }
155 
156  function flush() {
157  return timerId === undefined ? result : trailingEdge(now());
158  }
159 
160  function debounced() {
161  var time = now(),
162  isInvoking = shouldInvoke(time);
163 
164  lastArgs = arguments;
165  lastThis = this;
166  lastCallTime = time;
167 
168  if (isInvoking) {
169  if (timerId === undefined) {
170  return leadingEdge(lastCallTime);
171  }
172  if (maxing) {
173  // Handle invocations in a tight loop.
174  timerId = setTimeout(timerExpired, wait);
175  return invokeFunc(lastCallTime);
176  }
177  }
178  if (timerId === undefined) {
179  timerId = setTimeout(timerExpired, wait);
180  }
181  return result;
182  }
183  debounced.cancel = cancel;
184  debounced.flush = flush;
185  return debounced;
186 }
187 
188 module.exports = debounce;