Skip to content

Instantly share code, notes, and snippets.

@newbenhd
Last active September 25, 2023 06:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save newbenhd/fd0aa0ad84c5a66949a6ff40ba94d7ce to your computer and use it in GitHub Desktop.
Save newbenhd/fd0aa0ad84c5a66949a6ff40ba94d7ce to your computer and use it in GitHub Desktop.
Ticker event emitter decorator with error propagation
/**
* Modify the function created in exercise 3.3 so that it produces an error if the timestamp at the moment of a
* tick (including the initial one that we added as part of exercise 3.3) is divisible by 5. Propagate the error
* using both the callback and the event emitter. Hint: use Date.now() to get the timestamp and the remainder (%)
* operator to check whether the timestamp is divisible by 5.
*/
const ticker = require('./ticker.js')
function callback(error, ...args) {
if (error) return console.error(error.message)
console.log(args.join(','))
}
const tickerDecoratorHandler = {
get(target, props) {
if (props === 'propagateErrorOnEvent') {
return propagateErrorOnEvent.bind(null, target)
} else {
return target[props]
}
}
}
function propagateErrorOnEvent(ee, eventName, cb) {
ee.on(eventName, function () {
try {
cb()
} catch (error) {
ee.emit('error', error)
}
})
return ee
}
function shouldNotDivisibleBy5() {
const lastNumberStr = Date.now().toString().at(-1)
if (lastNumberStr === '5' || lastNumberStr === '0') throw Error('Current time is divisible 5')
}
const ee = new Proxy(ticker(1000, callback), tickerDecoratorHandler)
ee.propagateErrorOnEvent('tick', shouldNotDivisibleBy5).on('error', callback)
/**
* Write a function that accepts a number an a callback as the arguments. The function will return an EventEmitter
* that emits an event called 'tick' every 50 milliseconds until the number of milliseconds is passed from the invocation
* of the function. The function will also call the callback when the number of milliseconds has passed, providing, as
* the result, the total count of tick events emitted. Hint: you can use setTimeout() to schedule another setTimeout()
* recursively.
*/
module.exports = function ticker(number, cb) {
const ee = new (require('events').EventEmitter)()
let count = 0
ee.on('tick', function (time) {
if (time > number) return cb(null, count)
setTimeout(function () {
ee.emit('tick', time + 50)
count++
}, 50)
})
process.nextTick(ee.emit.bind(ee, 'tick', 0))
return ee
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment