My first question! I really want to ask him correctly, so please help me improve it if I could ask for it better.
Here is the only question I found that seemed remotely connected, but I couldn’t figure out how to relate it to what I was trying to do (their question is JQuery-specific, mine is Node.JS specific-ish [although I found the browser version EventEmitter and was able to check in the browser]): Run the function once for the event package using jQuery
Question
I have a process that, as I know, will generate a burst of events over a period of time.
To simulate this process, I wrote this code:
const EventEmitter = require('events'); class MyEmitter extends EventEmitter {} const myEmitter = new MyEmitter(); myEmitter.on('event', (burstID) => { console.log('an event occurred!', burstID); }); const millisecondsToSustainBurst = 3000 ; const millisecondsBetweenPossibleEventEmissions = 200 ; const millisecondsUntilStartNextBurst = 5000 ; const millisecondsUntilNoMoreBursts = 23000 ; const now = new Date() ; console.log('Time now: ' + now + '; should run until about ' + new Date(now.getTime() + millisecondsUntilNoMoreBursts)) ; const doRandomEmitBurst = (startTimestamp, millisecondsToSustainBurst, burstID) => { if (Math.random() > 0.5) myEmitter.emit('event', burstID) ; if ( !((new Date()) - startTimestamp > millisecondsToSustainBurst) ) setTimeout(() => doRandomEmitBurst(startTimestamp, millisecondsToSustainBurst, burstID), millisecondsBetweenPossibleEventEmissions) ; } const doRegularRandomBursts = (startTimestamp, millisecondsUntilStartNextBurst, millisecondsUntilNoMoreBursts, callback) => { if ( !((new Date()) - startTimestamp > millisecondsUntilNoMoreBursts) ) { const now = new Date() ; console.log('Time now: ' + now + '; starting random-event burst which will run for ' + (millisecondsToSustainBurst/1000) + ' seconds. ') ; setTimeout(() => doRegularRandomBursts(startTimestamp, millisecondsUntilStartNextBurst, millisecondsUntilNoMoreBursts, callback), millisecondsUntilStartNextBurst) ; doRandomEmitBurst(new Date(), millisecondsToSustainBurst, 'burstThatStartedAt' + now.getHours() + 'h' + now.getMinutes() + 'm' + now.getSeconds() + 's') ; } else callback() ; } doRegularRandomBursts(new Date(), millisecondsUntilStartNextBurst, millisecondsUntilNoMoreBursts, () => console.log('Done at ' + (new Date()))) ; const myBurstDetectedEmitter = new MyEmitter() ; // NOW, what do I do HERE to say: // I've seen a number of events occur in a 5-second period // Now they've stopped // Therefore I'm going to emit a different kind of event
Now let's say that I want to listen to these surges.
I want to make sure that the package has ended before taking further action.
How can I do it?
What I tried so far
To start, I can create a global "var" (yuck-I'd to avoid permutations) as follows:
var timeLastUpdated = {} ;
... and then...
function keepCheckingTimeLastUpdated(keyForUpdateCheck, callback) { const timestampToCheckInOneSecond = (typeof timeLastUpdated[keyForUpdateCheck] !== 'undefined' ? timeLastUpdated[keyForUpdateCheck] : (new Date())) ; setTimeout(() => { console.log( 'checking if modifications to "' + keyForUpdateCheck + '" have occurred since ' + timestampToCheckInOneSecond ) ; if (timeLastUpdated[keyForUpdateCheck] === timestampToCheckInOneSecond) { delete timeLastUpdated[keyForUpdateCheck] ; callback() ; } else keepCheckingTimeLastUpdated(keyForUpdateCheck, callback) ; }, 5000) ; } const makeNotificationHandler = () => (keyForUpdateCheck) => { const timeNow = new Date() ; if (typeof timeLastUpdated[keyForUpdateCheck] === 'undefined') keepCheckingTimeLastUpdated(keyForUpdateCheck, () => console.log(keyForUpdateCheck + ' changed')) ; timeLastUpdated[keyForUpdateCheck] = timeNow ; } ; myEmitter.on('event', makeNotificationHandler()) ;
It just looks like an anti-pattern (I hope that I use this term correctly). My gut says that having a global object is the wrong approach here, and that there is a more functional programming solution.
FOR INTERESTED ONLY:
(feel free to ignore the answers to the questions)
Added complication: in my example, the code “burstID” would never be the same, but in the real world it could be. I would like to wait until a certain amount of time has passed since the last appearance of "burstID" to find out if there really has been a spike in the changes.
For context, in a real application, I configure "LISTEN" in the PostGres database using node-postgres . "burstID" is the primary key in one table and is also used as a foreign key in several other tables. I listen to all the tables that use the shared key, and the message I return contains that key.