forked from meteor/meteor
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfunc-utils.js
More file actions
63 lines (53 loc) · 1.82 KB
/
func-utils.js
File metadata and controls
63 lines (53 loc) · 1.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
// Return a function that coalesceses calls to fn that occur within delay
// milliseconds of each other, and prevents overlapping invocations of fn
// by postponing the next invocation until after fn's fiber finishes.
exports.coalesce = function(delayMs, callback, context) {
var pending = false;
var inProgress = 0;
delayMs = delayMs || 100;
function coalescingWrapper() {
var self = context || this;
if (inProgress) {
// Indicate that coalescingWrapper should be called again after the
// callback is no longer in progress.
++inProgress;
return;
}
if (pending) {
// Defer to the already-pending timer.
return;
}
new Promise(
resolve => setTimeout(resolve, delayMs)
).then(function thenCallback() {
// Now that the timeout has fired, set inProgress to 1 so that
// (until the callback is complete and we set inProgress to 0 again)
// any calls to coalescingWrapper will increment inProgress to
// indicate that at least one other caller wants fiberCallback to be
// called again when the original callback is complete.
pending = false;
inProgress = 1;
try {
callback.call(self);
} finally {
if (inProgress > 1) {
Promise.resolve().then(thenCallback);
pending = true;
}
inProgress = 0;
}
});
}
return wrap(coalescingWrapper, callback);
};
function wrap(wrapper, wrapped) {
// Allow the wrapper to be used as a constructor function, just in case
// the wrapped function was meant to be used as a constructor.
wrapper.prototype = wrapped.prototype;
// https://medium.com/@cramforce/on-the-awesomeness-of-fn-displayname-9511933a714a
var name = wrapped.displayName || wrapped.name;
if (name) {
wrapper.displayName = name;
}
return wrapper;
}