0

I know that Nodejs is supposed to be different to other laguages due to the event loop, what makes it difficult to understand at first. However there's no way I can understand the following code (I managed to make it work, but no logic explanation).

I create new instances of a SSH connection each time I receive an special request, let's say:

sshCons = {};

sshObjt = new Connection();
sshCons[request_id] = sshObjt;
sshObjt.connect(); //and son on...

So I create a new Connection and "store" it in what we can understand as an "associative array", even if I think that it's just an Object that carries properties and their values. The question is, if I place this code after the lines written above:

sshObjt.on('data', function() {
    // CODE
});

How does Node know which sshObjt is the one that emits the event if I created multiple sshObjts and "stored" them? I previously tried to loop over the sshCons object but that shouldn't be the appropriate way of handling this. In case I'm wrong, which should be the proper way of handling events of multiple objects "stored" in sshCons object?

5
  • I'm not 100% sure, but chances are that in the callback this will refer to the emitting "sshObjt". Commented Aug 28, 2014 at 3:46
  • That makes sense. But the thing is, as I "make new sshObjts" constantly and therefore "overwrite" the last created sshObjt, I thought Node would only attend the data event of the latest created sshObjt. I hope I could explain myself Commented Aug 28, 2014 at 3:49
  • 1
    You overwrite the variable, you do not manipulate the object itself that was stored there Commented Aug 28, 2014 at 3:53
  • 1
    Although you are overwriting the sshObjt, you are assigning it with the event handler for data event at the moment you create it. The current instance of sshObjt is assigned with it's own even handler. It is more of a javascript question in general than node. :) Commented Aug 28, 2014 at 3:53
  • Thanks to Patric and Maverick. Your explanations where completely eye opening, thanks. Commented Aug 28, 2014 at 4:01

1 Answer 1

5

As Kay says, this has a decent chance to be the object that triggered the event; but that is up to whoever wrote the code for Connection. If it does not, it might be giving the handler an argument that has the receiver. (You are not giving any details as to where Connection comes from, so we can't check for you what exactly it does and doesn't provide.) If all else fails, and the library designer failed to provide the receiving object anywhere, you can create a closure:

sshObjt.on('data',
  (function(receiver) {
    return function() {
      // CODE where `receiver` is correct
    };
  })(sshObjt)
);

As to the worry from your comment to Kay, that is unfounded. When you attach a handler to an object, you attach the handler to the object - not to the variable that contains it. It's just like this:

var annas_husband = { name: "Tim", occupation: "mechanic" }
var joeys_dad = annas_husband;
joeys_dad.occupation = "supervisor";
annas_husband // => { name: "Tim", occupation: "supervisor" }

You didn't change joeys_dad's occupation. You changed Tim's. Since both annas_husband and joeys_dad are Tim, it happens to both. And conversely, which pertains to your case:

var guy;
var guys = [];

guy = { name: "Jake", occupation: "mechanic" }
guys.push(guy);

guy = { name: "Tim", occupation: "mechanic" }
guys.push(guy);
guy.occupation = "supervisor"

guy = { name: "Jeff", occupation: "mechanic" }
guys.push(guy);

guys
// => [
//      { name: "Jake", occupation: "mechanic" },
//      { name: "Tim", occupation: "supervisor" }
//      { name: "Jeff", occupation: "mechanic" },
//    ]

Here, again, you didn't change guy's occupation, you changed Tim's. Jake and Jeff weren't the guy at that time, so they did not get the promotion. on works exactly the same way - it attaches an event to an object, regardless in which variable the object resides currently, or in the future.

Sign up to request clarification or add additional context in comments.

3 Comments

"When you attach a handler to an object, you attach the handler to the object - not to the variable that contains it" This was pretty much the sentence I've been looking for. Thanks. The library is ssh2 from mscdex github.com/mscdex/ssh2
Then I think you have a logic error in your code: Connection does not emit data, the streams you get from Connection do. (Nothing to do with this question, just thought to mention it.)
That's right, I didn't want to complicate the question explaining stream was an object that came from sshObjt.shell() ... I tried to make it simple and apply to the context of data event. Anyway I could have made the example with a connected event which is really emitted by the object (I guess)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.