gpt4 book ai didi

javascript - 我是否需要关闭每个具有等待结果回调的方法?

转载 作者:太空宇宙 更新时间:2023-11-04 00:44:06 26 4
gpt4 key购买 nike

当我意识到当从数据库检索数据很慢时,数据可能随时发生变化时,我正在使用 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 绑定(bind)到回调,如下所示:

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 变量不会被覆盖,并且会按预期工作。

关于javascript - 我是否需要关闭每个具有等待结果回调的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35519103/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com