当我在Google上搜索Promisify Socket.IO时,我感到有点惊讶。这是不常见的吗?
我也有麻烦自己宣传:
Promise.promisifyAll(io)
io.onceAsync('connect')
.then((socket) => ...)
.catch((err) => console.log(error))
这总是会触发错误情况,我假设因为.once
是一个只有一个参数的回调,其中Promises期望第一个参数是错误。知道如何处理这类事情吗?
答案 0 :(得分:25)
我可以想到承诺一般不适合socket.io和EventEmitter
接口的几个原因:
在大多数情况下,socket.io是一个事件驱动的接口,并且承诺不会在架构上与可能出现多次的事件对齐(因为承诺是一次性设备)。是的,您可以使用.connect()
的承诺,但不能使用传入消息。因此,大多数人(包括我自己)可能认为使用promises半边界而另一半使用事件处理程序是有意义的。最好在整个API中使用一个模型。
Promise.promisifyAll()
需要node.js样式的异步回调(错误值作为第一个参数,数据作为第二个参数),这不是任何socket.io事件处理程序回调的内容使用。为了使承诺与connect
事件一起工作,您必须编写自己的自定义promsification,这可能比仅使用它所编写的事件处理程序更多的工作。
如果您尝试将事件的下一次出现与其他异步事件(通常不会做的事情)进行协调,则上述情况可能是例外情况,在这种情况下,承诺可能对协调有用。例如,假设您想知道三个单独的异步操作何时全部完成,其中一个是下一次发生的socket.io事件。然后,手动宣传该事件可能是有意义的,这样您就可以使用promises来协调多个异步操作。
但是对于正常的socket.io用法,承诺并不是一个很好的架构设计。同样,您通常不会在网页中使用promises作为点击处理程序。
仅供参考,如果您只想宣传connect
操作,可以像这样手动执行:
io.connectAsync = function(url, options) {
return new Promise(function(resolve, reject) {
io.connect(url, options);
io.once('connect', function(socket) {
resolve(socket);
});
io.once('connect_error', function() {
reject(new Error('connect_error'));
});
io.once('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
});