2014-02-13 35 views
5

作为持续努力的一部分,我正在改变目前的回调技术,以承诺使用blue-bird承诺库。如何在承诺中使用Socket.IO?

我想用Socket.IO来实现这个技巧。

  • 我该如何使用带有promise的Socket.IO而不是回调函数?
  • 是否有任何标准的方式与Socket.IO做到这一点?任何官方解决方案
+0

看看如果你没有强烈坚持Socket.IO,你可以考虑包裹成承诺平原的WebSockets。请参阅https://stackoverflow.com/questions/42304996/javascript-using-promises-on-websocket – vitalets

回答

1

蓝鸟(和许多otherpromise库)提供了帮助者方法来包装你的节点样式函数来返回一个承诺。

var readFile = Promise.promisify(require("fs").readFile); 

readFile("myfile.js", "utf8").then(function(contents){ ... }); 

https://github.com/petkaantonov/bluebird/blob/master/API.md#promisification

返回将包裹给nodeFunction的功能。而不是 进行回调,返回的函数将返回一个承诺,其命令由给定节点函数的回调行为决定。 节点函数应符合node.js约定,接受 回调作为最后一个参数,并将错误的回调调用为 第一个参数和第二个参数的成功值。

+0

当然,我知道,但我正在寻找官方支持socket.io/promises,如mongoose的'exec() '返回'Promise'对象。 –

+2

Gotcha。大多数websocket模块都使用了API。将基于回调的api转换为承诺是容易的,而对于使用eventemitter的东西则更不容易。 –

3

您可能会考虑Q-Connection,它有助于RPC使用promises作为远程对象的代理,并且可以使用Socket.IO作为消息传输。

+0

感谢q lib! –

1

这里https://www.npmjs.com/package/socket.io-rpc

var io = require('socket.io').listen(server); 
var Promise = require('bluebird'); 
var rpc = require('socket.io-rpc'); 

var rpcMaster = rpc(io, {channelTemplates: true, expressApp: app}) 
     //channelTemplates true is default, though you can change it, I would recommend leaving it to true, 
     //     false is good only when your channels are dynamic so there is no point in caching 
    .expose('myChannel', { 
    //plain JS function 
    getTime: function() { 
     console.log('Client ID is: ' + this.id); 
     return new Date(); 
    }, 
    //returns a promise, which when resolved will resolve promise on client-side with the result(with the middle step in JSON over socket.io) 
    myAsyncTest: function (param) { 
     var deffered = Promise.defer(); 
     setTimeout(function(){ 
      deffered.resolve("String generated asynchronously serverside with " + param); 
     },1000); 
     return deffered.promise; 
    } 
}); 


io.sockets.on('connection', function (socket) { 
    rpcMaster.loadClientChannel(socket,'clientChannel').then(function (fns) { 
     fns.fnOnClient("calling client ").then(function (ret) { 
      console.log("client returned: " + ret); 
     }); 
    }); 

});