Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write an event emitter in node.js that let's you create a function "myFunction" but then call either success or failure when it runs?

For example, I have seen functions like this, which are handy to use:

myFunction(data).
  success(function() { // success! }).
  fail(function() { // fail! });

I can't see an obvious way how to implement that. Here is my sad attempt after looking at the Node.js docs:

var EventEmitter = require('events').EventEmitter;
var testEmitter = function(x) {
  var e = new EventEmitter();

  if (x) {
    e.emit('success', 'got: ' + x);
  } else {
    e.emit('failure', 'no x passed')
  }

  return e;
}

Obviously, this won't work when you try to call it:

testEmitter('hello').
  success(console.log('success!')).
  failure(console.log('failure!'));

  // TypeError: Object #<EventEmitter> has no method 'success'

What's the best way to implement this pattern?

like image 617
Lavamantis Avatar asked Nov 05 '13 19:11

Lavamantis


2 Answers

This can be "improved" to:

var EventEmitter = require('events').EventEmitter;

var testEmitter = function(x) {
  var e = new EventEmitter();

  process.nextTick(function(){
    if (x) {
      e.emit('success', 'got: ' + x);
    } else {
      e.emit('failure', 'no x passed')
    }
   })

  var self = {};
  self.success = function(f) {
    e.on('success',f);
    return self;
  };
  self.failure = function(f) {
    e.on('failure',f);
    return self;
  };
  return self;
};

testEmitter("hello").success(function(results){
  console.log('success!',results);
}).failure(function(error){
  console.log('failure!' + error);
})
like image 150
lipp Avatar answered Sep 24 '22 18:09

lipp


How about this? I have used process.nextTick to simulate the async work that you want to do in your function.

var EventEmitter = require('events').EventEmitter;

var testEmitter = function(x) {
  var e = new EventEmitter();

  process.nextTick(function(){
      if (x) {
        e.emit('success', 'got: ' + x);
      } else {
        e.emit('failure', 'no x passed')
      }
  })

  return e;
}

testEmitter("hello").on("success", function(results){
    console.log('success!' + results);
}).on("failure", function(error){
    console.log('failure!' + error);
})
like image 21
Sudsy Avatar answered Sep 22 '22 18:09

Sudsy