我是否需要为每个具有等待结果回调的方法关闭
Do I need closure for every single methods that has a wait-for-result callback?
我正在使用 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 在用户 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)
});
});
参考: https://github.com/loverajoel/jstips/blob/gh-pages/_posts/en/2016-02-03-implementing-asynchronous-loops.md
我认为你的第一个例子应该可以正常工作。例如,请参阅以下内容:
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);
}
你必须把它包装成IIFE,就像这样:
for (var i = 0; i < 2; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000*i);
}(i));
}
或者将i
绑定到回调,如下所示:
for (var i = 0; i < 2; i++) {
setTimeout(function(i) {
console.log(i);
}.bind(null, i), 1000*i);
}
我个人更喜欢第二种方法。
但是,当您多次调用异步函数时,您不需要 IIFE,因为此函数本身就是一个闭包。例如:
function test(i) {
setTimeout(function() {
console.log(i);
}, 1000*i);
}
test(0);
test(1);
每次调用 test()
时,都会创建另一个作用域,因此不会覆盖 i
变量,并且会按预期工作。
- 将web服务回调的结果绑定到Javascript中的调用函数
- 返回循环中调用的回调结果的串联
- 从回调函数返回 AJAX 结果
- MongoDB:$addToSet Meteor中的重复结果回调
- node.js+MySQL;JSON结果-回调问题&没有响应客户端
- 如何通过回调访问nodejs中的mongodb计数结果
- 如何使用异步并行将所有回调结果合并到最终回调中
- 根据多个回调结果的结果执行最终回调
- 错误的排序回调-结果仍然正确
- bootstrapvalidatorremote的回调结果是json
- 链排队回调结果
- C#处理回调结果
- 如何一次显示所有回调结果(格式化)
- 如何访问angularjs回调结果jsonp
- Nodejs如何在没有settimeout的情况下访问回调结果
- 在单独的函数中使用节点中的回调结果
- 茉莉间谍以假ajax调用来测试回调结果
- nodejs回调don'我不理解回调结果是如何通过参数得出的
- Nodejs如何使用函数的回调结果
- 将回调结果写入页面