Answer the question
In order to leave comments, you need to log in
Is there a better way to go from events to callbacks in NodeJS?
there is a third-party module inherited from EventEmitter, let's call it SuperModule. when a certain #start method is called, the error or started event is emitted. passing a callback to #start is not provided by the module developer.
it is necessary to execute a chain of asynchronous function calls, one of the links of which is
the #start call.
you need to provide support for such a call (with the transfer of a callback): SuperModuleInstance.start(function(err){...});
Now it is implemented as follows:
var SuperModule = require('SuperModule');
SuperModule.prototype.startcb = function(callback){
var cb = function(err){
this.removeListener('error', cb);
this.removeListener('started', cb);
callback(err); // err == null при started
}
this.on('started', cb);
this.on('error', cb);
this.start();
}
...
async.series([
...,
SuperModuleInstance.startcb.bind(SuperModuleInstance),
...],
finalCallback);
Answer the question
In order to leave comments, you need to log in
Use an adapter . Like this:
var SuperModuleAdapter = function () {
this.adapted = new SuperModule()
}
SuperModuleAdapter.prototype = {
start: function (callback) {
var cb = function(err){
this.adapted.removeListener('error', cb);
this.adapted.removeListener('started', cb);
callback(err); // err == null при started
}
this.adapted.on('started', cb);
this.adapted.on('error', cb);
this.adapted.start();
}
}
Here are more options:
var SuperModule = require('SuperModule');
var start_ = SuperModule.prototype.start;
SuperModule.prototype.start = function(cb){
var fn = onceDelegate(cb);
this
.once('started', fn)
.once('error', fn)
;
start_.call(this);
};
function onceDelegate(fn) {
return function(){
var x_ = fn;
fn = null;
x_ && x_.apply(null, arguments);
};
}
// ИЛИ, если сделать более общим:
function callbackInjector(Ctor, method, events) {
var orig_ = Ctor.prototype[method];
Ctor.prototype[method] = function(){
var args = Array.prototype.slice.call(arguments),
cb = args.pop(),
listener = onceDelegate(cb),
imax = events.length,
i = -1
;
while(++i < imax) this.once(events[i], listener);
return orig_.apply(this, args);
}
};
callbackInjector(SuperModule, 'start', ['started', 'error']);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question