javascript 带有承诺或异步回调的 Socket.io
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21678213/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Socket.io with promise or async callbacks
提问by Johan Nordberg
This might be kind of an anti pattern, but what would be the best way to simulate a a promise callback
when emitting data from client to server using socket.io
?
这可能是一种反模式,但是在使用 将promise callback
数据从客户端发送到服务器时模拟 aa 的最佳方法是socket.io
什么?
For some event I would very much like it to behave like a normal get request so the client send data to the server and the server could reply with a response and then resolve or reject the promise.
对于某些事件,我非常希望它表现得像一个普通的 get 请求,这样客户端将数据发送到服务器,服务器可以回复一个响应,然后解决或拒绝承诺。
采纳答案by freakish
Well, you have to keep track of requests. So I would start with a "global" counter (it does not have to be global, it's enough that it is visible for two functions defined bellow) which will be incremented on each request (and emitted together with it) and a "global" handler namespace. The code may look like that:
好吧,您必须跟踪请求。所以我将从一个“全局”计数器开始(它不必是全局的,它对下面定义的两个函数可见就足够了),它将在每个请求(并与其一起发出)和“全局”计数器上增加处理程序命名空间。代码可能如下所示:
var COUNTER = 0,
HANDLERS = {};
var custom_get = function(data, clb) {
COUNTER++;
var msg = {id: COUNTER, data: data};
socket.emit("GET", JSON.stringify(msg));
HANDLERS[COUNTER] = clb;
};
socket.on("GET", function(data) {
var res = JSON.parse(data);
HANDLERS[res.id](res.data);
delete HANDLERS[res.id];
});
Now you just have to make sure that the server will respond with the same format, i.e. JSON
现在你只需要确保服务器将以相同的格式响应,即 JSON
{id:X, data:Y}
and will use the same ID for the same request. You can use this code like this:
并将对相同的请求使用相同的 ID。您可以像这样使用此代码:
custom_get("test", function(res) {
console.log(res);
});
You can also play with that code adding for example timeouts.
您还可以使用该代码添加例如超时。
Finally have a look at JSON-RPC. It's a proper protocol which is simple and you can easily implement it over WebSocket.
最后看看JSON-RPC。这是一个适当的协议,它很简单,您可以通过 WebSocket 轻松实现它。
回答by Greg Tatum
Here's what I did. I created a function that emits a socket command, and then returns a promise. My one caveat is I haven't done a lot with this code yet, so it might need some tweaking. It also requires Q for its promises/deferreds.
这就是我所做的。我创建了一个发出套接字命令的函数,然后返回一个承诺。我的一个警告是我还没有对这段代码做很多事情,所以它可能需要一些调整。它还需要Q 为其 promises/deferreds。
Client function definition:
客户端函数定义:
var EmitPromise = function( socket, command, data ) {
var deferred = Q.defer();
socket.emit(command, data, function( response ) {
if( typeof response === "object" ) {
if( response.success === true ) {
deferred.resolve(response.data);
} else {
if( typeof response.message === "string" ) {
deferred.reject( response.message );
} else {
deferred.reject( "The request was not successful." )
}
}
} else {
deferred.reject( "The response to your request could not be parsed." );
}
});
return deferred.promise.timeout( 30000, "The request took too long to respond." );
}
Client side code to make the call:
进行调用的客户端代码:
EmitPromise( socket, "getValue", "username" )
.then(
function( data ) {
console.log(data);
return EmitPromise( socket, "getValue", "anotherValue" );
}, function( message ) {
console.log(message);
}
).then(
//Chain your commands from here
);
Server side handler
服务器端处理程序
The most important part of this handler is that the second parameter, here named setValueResult must be called with an object that contains a "success" key that holds a true or false value. This was a decision on my part to provide a way to reject the promise in case of some kind of error on the server side.
这个处理程序最重要的部分是第二个参数,这里命名为 setValueResult 必须用一个对象调用,该对象包含一个包含真或假值的“成功”键。这是我的决定,以提供一种在服务器端出现某种错误时拒绝承诺的方法。
socket.on( 'getValue', function( valueName, setValueResult ) {
var value = getValue(valueName) //Do something with value here
if( value ) {
setValueResult({
success : success,
data : value
});
} else {
setValueResult({
success : success
message : "Unable to retrieve value"
});
}
}
回答by Tsunamis
The current socket.io version 2.1.0 allows sending callback functions to the server:
当前的 socket.io 版本 2.1.0 允许向服务器发送回调函数:
Client
客户
socket.emit('ferret', 'tobi', (data) => {
console.log(data); // data will be 'woot'
});
Server
服务器
socket.on('ferret', (name, callback) => {
callback('woot');
});
You can also create a promise before the emit and resolve it in the client callback function.
您还可以在发出之前创建一个承诺并在客户端回调函数中解决它。