我正在使用socket.io和MySQL数据库工作在nodejs服务器上,当我意识到当数据从数据库检索很慢时,数据可能随时发生变化。 比方说,例如,在每个套接字连接上,我想在数据库发出X数据时查询数据库中的用户信息。
io.on('connection', function(socket) {
console.log('User connected');
socket.on('fetchTable', function(data) {
var number = data.number;
database.getTable(number, function(error, result) {
// We'll take it that result is constant for both: 1
socket.emit('fetchTableResult', result + number);
});
});
});
如果2个用户在同时连接(用户1的号码:1,用户2的号码:2),用户1请求数据库 BEFORE 用户2但是数据库要为用户1和已处理用户2的数据返回结果太慢。返回的数据会有所不同吗?两个用户都将获得'3'作为'fetchTableResult'数据吗?套接字现在不是用户2的套接字吗?
解?
io.on('connection', function(socket) {
console.log('User connected');
socket.on('fetchTable', function(data) {
var number = data.number;
(function(socket, number) {
database.getTable(number, function(error, result) {
// We'll take it that result is constant for both: 1
socket.emit('fetchTableResult', result + number);
});
})(socket, number)
});
});
如果是这种情况,如果在database.getTable
内,我有另外一种方法,例如获取网站的HTML内容需要花费一些时间,我是否真的需要另一个封闭内容?
例如:
io.on('connection', function(socket) {
console.log('User connected');
socket.on('fetchTable', function(data) {
var number = data.number;
(function(socket, number) {
database.getTable(number, function(error, result) {
// We'll take it that result is constant for both: 1
(function(socket, result) {
// fetch website html data
socket.emit('fetchTableResult', result + number);
})(socket, result)
});
})(socket, number)
});
});
答案 0 :(得分:1)
我认为你的第一个例子应该可以正常工作。请参阅此示例:
document.addEventListener("click", function(event) {
var x = event.x;
setTimeout(function() {
console.log(x);
}, 1000);
});

尝试在短时间内点击两个不同的地方。正如预期的那样,您将得到不同的结果。
当你在循环中执行异步函数时,你需要一个闭包(实际上是一个IIFE),例如,这不会按预期工作:
for (var i = 0; i < 2; i++) {
setTimeout(function() {
console.log(i);
}, 1000*i);
}
&#13;
你必须把它包裹起来IIFE,就像这样:
for (var i = 0; i < 2; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000*i);
}(i));
}
&#13;
或将i
绑定到回调,如下所示:
for (var i = 0; i < 2; i++) {
setTimeout(function(i) {
console.log(i);
}.bind(null, i), 1000*i);
}
&#13;
就个人而言,我更喜欢第二种方法。
但是,当您多次调用异步函数时,您不需要IIFE,因为此函数本身就是一个闭包。例如:
function test(i) {
setTimeout(function() {
console.log(i);
}, 1000*i);
}
test(0);
test(1);
&#13;
每次调用test()
时,都会创建另一个范围,因此i
变量不会被覆盖,并且按预期工作。