Автоматическое завершение любого обратного вызова node.js - PullRequest
2 голосов
/ 23 июня 2011

Возможно ли написать код, который обернет любой ноль / н-колбэк моей собственной функцией? (Когда я говорю «функция обратного вызова ввода / вывода», я имею в виду функцию, которая вызывается после некоторого действия ввода / вывода)

Зачем мне такая вещь? пример: у меня есть сервер socket.io У меня есть куча глобальных функций, которые я на самом деле получаю в качестве входных данных (я не могу изменить их, даже не читая, я просто вставляю их как есть в моем коде)

обратный вызов socket.io.connect (socket, ... callback) взаимодействует с этими глобальными функциями. Теперь при новом подключении мы устанавливаем доступ к текущему сокету на глобальном уровне. программисты, написавшие эти глобальные функции, знают о переменной currentSocket и используют ее ..

Проблема в том, что после вызова некоторой асинхронной функции ввода-вывода другой пользователь / сокет может подключиться и изменить currentSocket, позже, когда асинхронная функция ввода-вывода будет выполнена, currentSocket будет равен другому пользователю / сокету а не исходный пользователь / сокет, который вызвал эту асинхронную функцию

Я подумал, что, может быть, мне удастся как-то автоматически обернуть обратный вызов ввода-вывода и закрыть переменную currentSocket, но я не уверен, как это сделать ... есть идеи?

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)
}

Ответы [ 3 ]

2 голосов
/ 10 августа 2011

Если все ваши функции совместно используют глобальную переменную currentSocket (и если вы не можете их изменить), невозможно иметь несколько соединений (если функции асинхронны).Если бы вы могли изменить их, было бы лучше просто передать сокет в качестве первого параметра вашим функциям.Другой способ - переместить определение currentSocket и ваши функции в обратный вызов io.sockets connection.В этом случае переменная currentSocket образует замыкание, и все должно работать как положено:

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)
  }

});
1 голос
/ 02 июля 2011

Если я правильно понимаю ваш вопрос, одним из способов его решения может быть использование цепочки псевдонимов.Вы можете передать исходный обратный вызов в выражение анонимной функции, которое возвращает выражение новой функции:

cb = (function (original) {
  return function () {
    // do something with original callback
    original();
    // add more functionality 
  }
})(cb); 
0 голосов
/ 05 августа 2011

Если вы хотите обернуть установленный метод в JS, способ сделать это - переименовать и заменить.

например,

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

Я бы предложил применить это в вашем случае использованияв этом случае, либо объект io.sockets, либо более глубокий объект, возможно, вплоть до метода EventEmitter.emit ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...