2014-02-13 67 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); 
     }); 
    }); 

});