开发者

Wrapping any node.js callback automatically

Is it possible to write code that wrap any node.js i/o-callback开发者_Python百科 with my own function? (When I say i/o-callback function I mean function that get invoked after some i/o action)

Why do I need such a thing? example: I have a socket.io server I have bunch of global functions that I am actually getting as an input (I can't change it, not even reading it, I just paste it as is in my code)

the callback of socket.io.connect(socket,...callback ) interact with those global functions. now upon new connection we set access to the current socket in a global level. the programmers who wrote those global function are aware of the currentSocket variable and uses it..

The problem is that after calling some async i/o function, some other user/socket might connect and change the currentSocket, later when the async i/o function will get executed the currentSocket will be equals to a different user/socket rather than the original user/socket that invoked that async-function

I thought maybe I can somehow auto-wrap the i/o callback and closure the currentSocket variable, yet I am not sure how to do that... any idea?

var currentSocket = undefined;
io.sockets.on('connection', function (socket) {
  currentSocket = socket;
  socket.on('msg', function (data) {
    global[data.functionToInvoke];
  });
});

//global function that I can't change or even analyze/read
//========================================================
function g1(){
   //might use currentSocket
   //might invoke async stuff like
   fs.readfile(...cb)
}
function g2(){
   //might use currentSocket
   //might invoke async stuff like
   redisClient.get(...cb)
}


If your functions all share the currentSocket global variable (and if you can't change them), it is not possible to have multiple connections (as long as the functions are async). If you could change them it would be best just to pass the socket as first parameter to your functions. Another way is to move the definition of currentSocket and your functions inside of the io.sockets connection callback. In this case the currentSocket variable forms a closure and everything should work as expected:

io.sockets.on('connection', function (socket) {
  var currentSocket = socket;
  socket.on('msg', function (data) {
    global[data.functionToInvoke];
  });

  //global function that I can't change or even analyze/read
  //========================================================
  function g1(){
     //might use currentSocket
     //might invoke async stuff like
     fs.readfile(...cb)
  }
  function g2(){
     //might use currentSocket
     //might invoke async stuff like
     redisClient.get(...cb)
  }

});


If I understand your question correctly one way to accomplish it could be via alias method chain. You can pass the original callback into anonymous function expression which returns new function expression:

cb = (function (original) {
  return function () {
    // do something with original callback
    original();
    // add more functionality 
  }
})(cb); 


If you want to wrap an established method in JS the way to do it is by renaming & replacing.

e.g.

 Array.prototype._toString = Array.prototype.toString;
 Array.prototype.toString = function(){ return "wrapped["+this._toString()+"]"; };
 console.log(["1","2","3"].toString());

I'd suggest applying that to your use case, in this case either the io.sockets object, or a deeper object, perhaps all the way down on the EventEmitter.emit() method.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜