Last active
September 25, 2023 06:04
-
-
Save newbenhd/fd0aa0ad84c5a66949a6ff40ba94d7ce to your computer and use it in GitHub Desktop.
Ticker event emitter decorator with error propagation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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