Only call a function once.
varonce=require('once')functionload(file,cb){cb=once(cb)loader.load('file')loader.once('load',cb)loader.once('error',cb)}
Or add to the Function.prototype in a responsible way:
// only has to be done oncerequire('once').proto()functionload(file,cb){cb=cb.once()loader.load('file')loader.once('load',cb)loader.once('error',cb)}
Ironically, the prototype feature makes this module twice ascomplicated as necessary.
To check whether your function has been called, usefn.called
. Once thefunction is called for the first time the return value of the originalfunction is saved infn.value
and subsequent calls will continue toreturn this value.
varonce=require('once')functionload(cb){cb=once(cb)varstream=createStream()stream.once('data',cb)stream.once('end',function(){if(!cb.called)cb(newError('not found'))})}
Throw an error if the function is called twice.
Some functions are expected to be called only once. Usingonce
for them wouldpotentially hide logical errors.
In the example below, thegreet
function has to call the callback only once:
functiongreet(name,cb){// return is missing from the if statement// when no name is passed, the callback is called twiceif(!name)cb('Hello anonymous')cb('Hello '+name)}functionlog(msg){console.log(msg)}// this will print 'Hello anonymous' but the logical error will be missedgreet(null,once(msg))// once.strict will print 'Hello anonymous' and throw an error when the callback will be called the second timegreet(null,once.strict(msg))