我需要在没有CORS标头的服务器上执行GET请求,所以我创建了一个非常简单的节点应用程序,它将为我做GET:
var io = require('socket.io')();
var request = require('request');
io.on('connection', function(socket) {
socket.on('get', function(url) {
request(url, function(error, response, body) {
socket.emit('response', body);
});
});
});
在客户端,我使用简单的get
功能:
var socket = io();
function get(url) {
return new Promise(function(resolve) {
socket.emit('get', url);
socket.once('response', function(data) {
resolve(data);
});
}
}
当我一次请求一个URL时,这很有用:
get('http://some/resource/1');
但是当我同时向不同的端点尝试多个请求时,它们都将返回相同的数据:
get('http://some/resource/1');
get('http://some/resource/2');
get('http://some/resource/3');
在这种情况下,所有3都会返回/resource/1
的数据。我知道这是因为socket.once('response')
回调会立即为所有3个请求添加,并且当返回数据时第一个,为它调用所有3个回调。
我是否有办法让每个socket.emit()
和socket.on()
相互配对?我知道我可以为每个发送添加一个唯一的ID并将其传回响应,或者使用消息本身中的唯一ID(类似socket.emit('get:a54jk14hf')
,但我希望有一个更简单的解决方案,如果有一个。
答案 0 :(得分:0)
问题是你通过在“get”函数中发出“once”钩子来覆盖socket.io的“response”事件。将它保留在那里是很好的,但你需要为“一次”提供一个独特的事件,这样四个独特的事件将会回来。这可以使用“url”作为键来完成。它看起来像这样:
服务器:
var io = require('socket.io')();
var request = require('request');
io.on('connection', function(socket) {
socket.on('get', function(url) {
request(url, function(error, response, body) {
socket.emit(
'response-' + url, // USING THIS INSTEAD OF JUST "response"
body
);
});
});
});
客户端:
var socket = io();
function get(url) {
return new Promise(function(resolve) {
socket.emit('get', url);
socket.once(
'response-' + url, // USING THIS INSTEAD OF JUST "response"
function(data) {
resolve(data);
});
}
}
我不确定这是否是您的要求,但上述方法也可以让您将正确的数据返回到Promise的“then”块。
get('http://some/resource/1').then(function (data) {
// the "data" is now guaranteed to be from resource "1"
// previous, it could have been from 1, 2, or 3
})