2016-05-21 12 views
1

Ich bin etwas überrascht, dass ich beim Googeln für Promisify Socket.IO nicht viel finde. Ist es so ungewöhnlich?Promisify Socket.IO/EventEmitter

Ich hatte auch Schwierigkeiten, es selbst promisify:

Promise.promisifyAll(io) 
io.onceAsync('connect') 
.then((socket) => ...) 
.catch((err) => console.log(error)) 

Dies immer den Fehlerfall auslöst, nehme ich an, weil .once nur ein Rückruf mit einem Argument ist, wo Promises die erste erwarten, dass der Fehler sein. Irgendeine Idee, wie man mit solchen Dingen umgeht?

+0

Was Google haben Sie? https://github.com/kriskowal/q-connection –

+0

yeah, native socket.io bitte – Mahoni

Antwort

11

Ich kann aus mehreren Gründen ein, warum Versprechungen nicht eine gute Passform mit socket.io und EventEmitter Schnittstellen sind im Allgemeinen:

  1. Zum größten Teil ist socket.io eine ereignisgesteuerte Schnittstelle und Versprechen Ordnen Sie sich nicht architektonisch mit Ereignissen, die mehr als einmal auftreten können (da ein Versprechen ein One-Shot-Gerät ist). Ja, Sie können ein Versprechen für .connect() verwenden, aber nicht für eingehende Nachrichten. Die meisten Leute (ich selbst eingeschlossen) denken wahrscheinlich nicht, dass es sinnvoll ist, eine halbe Schnittstelle mit Versprechungen und die andere Hälfte mit Event-Handlern zu verwenden. Wahrscheinlich besser, ein Modell für die gesamte API zu verwenden.

  2. Promise.promisifyAll() erfordert Async-Callbacks vom Typ node.js (mit Fehlerwert als erstes Argument und Daten als zweites Argument), und das ist keiner der Callbacks für die Ereignishandler socket.io. Um Versprechen zu machen, die mit etwas wie dem connect-Ereignis arbeiten, müssten Sie Ihre eigene benutzerdefinierte Ankündigung schreiben, die wahrscheinlich mehr Arbeit ist, als nur den Event-Handler zu verwenden, für den sie geschrieben wurde.

Eine Ausnahme von der oben könnte sein, wenn Sie das nächste Auftreten eines Ereignisses mit anderen asynchroner Ereignisse zu koordinieren versuchen, (etwas, das nicht in der Regel der Fall ist), in dem Fall Versprechen für die Koordination nützlich sein könnten. Als Beispiel wollten Sie wissen, wann drei separate asynchrone Vorgänge abgeschlossen waren, von denen einer das nächste Vorkommen eines socket.io-Ereignisses war. Dann könnte es sinnvoll sein, dieses Ereignis manuell zu promoten, damit Sie Versprechen zur Koordinierung Ihrer mehreren asynchronen Vorgänge verwenden können.

Aber für normale socket.io-Nutzung, Versprechen sind einfach nicht eine gute architektonische Passform. Ebenso würden Sie normalerweise keine Versprechen für einen Klick-Handler in einer Webseite verwenden.


FYI, wenn Sie nur die connect Operation promisify möchten, können Sie dies manuell tun, wie folgt:

io.connectAsync = function(url, options) { 
    return new Promise(function(resolve, reject) { 
     io.connect(url, options); 
     io.on('connect', function(socket) { 
      resolve(socket); 
     }); 
     io.on('connect_error', function() { 
      reject(new Error('connect_error')); 
     }); 
     io.on('connect_timeout', function() { 
      reject(new Error('connect_timeout')); 
     }); 
    }); 
} 


io.connectAsync().then(function(socket) { 
    // connected here 
    socket.on('someMsg', function() { 
     // process message here 
    }); 
}, function(err) { 
    // error connecting here 
}); 
+3

@Mahoni - Hat dies Ihre Frage beantwortet? Wenn dies der Fall ist, klicke bitte auf das grüne Häkchen links neben der Antwort, um dies der Community anzuzeigen und dir einige Reputationspunkte zu verdienen, um das richtige Verfahren hier beim Stack-Überlauf zu befolgen. Wenn nicht, erläutern Sie bitte, welcher Teil Ihrer Frage nicht beantwortet wurde. – jfriend00

+0

Die Zuhörer innerhalb des Versprechens müssen "einmal" sein. Andernfalls haben Sie mehrere Anrufe, die bei erneuten Verbindungen aufgelöst oder abgelehnt werden. – Hkan

+0

@Hkan - Zusätzliche Aufrufe zum Auflösen oder Zurückweisen werden ignoriert, da ein Versprechen nur einmal aufgelöst oder abgelehnt werden kann. – jfriend00