setInterval with setTimeout semantics
Often you want to execute an operation at certain intervals, pending
completion of the operation. For asynchronous operations, setInterval()
is
not sufficient for this scenario, as it can execute the operation a second
time even if the first one is still in flight. A refresh like operation is a
common use case.
Instead, reissue uses setTimeout()
under the hood, queuing up a second
execution only after the first exeuction has completed. If the time elapsed
exceeds that of the specified interval, the second execution will be invoked
immediately. This means that the behavior of reissue may not be identical to
that of setInterval()
for asynchronous operations. This is intended behavior.
Install the module with: npm install reissue
To begin, create a reissue object, which will return you an handler object:
var reissue = require('reissue');
var handler = reissue.create({
func: function print(callback) {
console.log('hi');
return callback();
},
interval: 1000
});
handler.start();
Calling start()
on the handler will begin the interval, and now reissue will
log 'hi' to the console once every second. Note the callback parameter passed
to the function - this callback must be called in order for the next
invocation to proceed.
reissue takes the following options to its create()
method:
opts.func
{Function} the function to execute. This function is invoked with a callback function as it's last parameter.opts.interval
{Number | Function} the interval in ms to execute the function, or a function that returns an interval, allowing usage of a dynamic interval.[opts.unref]
{Boolean} if true, will unref the timers allowing the process to exit gracefully without having to call stop on the handler.[opts.timeout]
{Number} an optional timeout in ms. if any invocation of the the supplied func exceeds this timeout, thetimeout
event is fired.[opts.context]
{Context} an optionalthis
context for the function. use this in lieu of nativebind()
if you are concerned about performance. reissue usesapply()
under the hood to do context/arg binding.[opts.args]
{Array} an optional array of arguments for the function. used in conjunction with the sameapply()
call as the context.
Returns: {Object} returns a handler object
The returned handler object exposes the following methods:
Starts the timer interval. Calling start()
while reissue is already active
will throw an exception.
delay
{Number} an optional delay in ms before first invocation. if no delay is provided, first invocation is synchronous (no setImmediate, no setTimeout). Note that0
is explicitly a valid value, and will be passed to setTimeout.
Returns: {undefined} returns nothing
Stops the timer interval. Takes no parameters. This will stop all further invocations of the function, even if they have already been scheduled.
Returns: {undefined} returns nothing
The handler object also emits the following events:
If your function returns an error to the callback, this event will be emitted. The subscribed function will receive an error as it's only parameter.
When the stop()
method is called, this event is emitted when either the
current invocation is successfully completed, or when the next scheduled
invocation is successfully cancelled. If the current invocation is "stuck" in
the sense that the callback never returns, the stop event will never fire.
If a timeout
value is specified, this event will be fired when any given
invocation of the function exceeds the specified value. However, if your user
supplied function is synchronous, and never gives up the event loop, it is
possible that this event may never get fired.
See API
Add unit tests for any new or changed functionality. Ensure that lint and style checks pass.
To start contributing, install the git prepush hooks:
make githooks
Before committing, run the prepush hook:
make prepush
Copyright (c) 2018 Alex Liu
Licensed under the MIT license.