Promisify Socket.IO/EventEmitter

Mah*_*oni 4 javascript node.js promise socket.io

在Google搜索Promisify Socket.IO时,我找不到多少这个事实,我感到有些惊讶.那不常见吗?

我也有麻烦自己宣传:

Promise.promisifyAll(io)
io.onceAsync('connect')
.then((socket) => ...)
.catch((err) => console.log(error))
Run Code Online (Sandbox Code Playgroud)

这总是触发错误情况,我假设因为.once只有一个参数的回调,其中Promises期望第一个是错误.知道如何处理这类事情吗?

jfr*_*d00 25

我可以想到一些原因,为什么promises不适合socket.io和EventEmitter接口:

  1. 在大多数情况下,socket.io是一个事件驱动的接口,并且承诺不会在体系结构上与多次发生的事件对齐(因为承诺是一次性设备).是的,您可以使用承诺.connect(),但不能使用传入消息.因此,大多数人(包括我自己)可能认为使用promises半边界而另一半使用事件处理程序是不合理的.在整个API中使用一个模型可能更好.

  2. Promise.promisifyAll()需要node.js样式的异步回调(错误值作为第一个参数,数据作为第二个参数),这不是任何socket.io事件处理程序回调使用的.为了使promises能够处理类似connect事件的事情,你必须编写自己的自定义promsification,这可能比仅使用它所编写的事件处理程序更多的工作.

上述情况的一个例外情况可能是,如果您尝试使用其他异步事件(通常不会执行的操作)协调下一次事件的发生,在这种情况下,promises可能对协调有用.例如,假设您想知道三个单独的异步操作何时全部完成,其中一个是下一次发生的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
});
Run Code Online (Sandbox Code Playgroud)

  • @Mahoni - 这回答了你的问题吗?如果是这样,请点击答案左侧的绿色复选标记,向社区表明,并在堆栈溢出时遵循正确的程序为自己赢取一些声誉点.如果没有,请解释您的问题的哪一部分未得到解答. (3认同)