I want to avoid polluting the top-level scope of my file – I am trying to encapsulate the variables into a closure.
Current code:
// global scope - I want to keep track fo these variables between function calls
const timeInMsToReleaseNotification = 1000 * 15; // 15 seconds
let queuedNotifications: Notification[] = [];
let timeoutId: NodeJS.Timeout | null = null;
const trackNotifications = (data: Notification) => {
if (timeoutId) {
clearTimeout(timeoutId);
}
queuedNotifications.push(data);
timeoutId = setTimeout(() => {
const foundData = queuedNotifications[0];
if (foundData) {
displayNotification(
foundData,
queuedNotifications.length > 1
? 'nearbyBatch'
: 'nearbySingle',
);
queuedNotifications = [];
timeoutId = null;
}
}, timeInMsToReleaseNotification);
};
How I would like it to work:
const trackNotifications = (data: Notification) => {
const timeInMsToReleaseNotification = 1000 * 15; // 15 seconds
let queuedNotifications: Notification[] = [];
let timeoutId: NodeJS.Timeout | null = null;
return () => {
if (timeoutId) {
clearTimeout(timeoutId);
}
queuedNotifications.push(data);
timeoutId = setTimeout(() => {
const foundData = queuedNotifications[0];
if (foundData) {
displayNotification(
foundData,
queuedNotifications.length > 1
? 'nearbyBatch'
: 'nearbySingle',
);
queuedNotifications = [];
timeoutId = null;
}
}, timeInMsToReleaseNotification);
}
};
// calling fn like this
trackNotifications(data)()
This is not working atm.
What am I doing wrong here?
2
Answers
Every time you call
trackNotifications()
you create a new, emptyqueuedNotifications
array. You need to wrap all the code in an IIFE to create a closure, so the declaration ofqueuedNotifications
is outside thetrackNotifications()
function.However, in ES6 you don’t need a closure for this. Variables declared with
let
andconst
are block-scoped, so you can simply put all the code inside a block.One thing you could do is wrap the whole thing within an IIFE. This limits the scope of the variables so only
trackNotifications
can access them.