你好Javascript / Node.js-Developer,
我遇到了异步Javascript的老问题,只给我一个数组的最后一项(如HERE和HERE所示)。不幸的是,所提供的解决方案都不适合我。
我在Node版本0.10.25上运行。我编译了一个最小的(不是)工作示例:
var neededTables = [{
name: "ipfix_exporters",
},{
name: "ipfix_messages",
}];
var params = {};
console.log('[1] Connected to hana-database');
neededTables.forEach(function(table) {
params.table = table;
console.log("Checking table: " + params.table.name);
checkForTable.bind(null, params)();
});
function checkForTable(thoseParams) {
setTimeout(
(function(myParams) { return function(err, rows) {
if(err) {
console.log(err);
return;
}
console.log("Table '"+myParams.table.name+"' does exist!");
}})(thoseParams), 1000);
}
预期输出:
[1] Connected to hana-database
Checking table: ipfix_exporters
Checking table: ipfix_messages
Table 'ipfix_exporters' does exist!
Table 'ipfix_messages' does exist!
Actuall 输出:
[1] Connected to hana-database
Checking table: ipfix_exporters
Checking table: ipfix_messages
Table 'ipfix_messages' does exist!
Table 'ipfix_messages' does exist!
我完全难过了。希望有人
答案 0 :(得分:4)
在此代码中:
neededTables.forEach(function(table) {
params.table = table;
console.log("Checking table: " + params.table.name);
checkForTable.bind(null, params)();
});
设置params.table时,foreach函数的每次迭代都会使用下一个表更新params.table。
当您以1000ms的超时时间调用下面的函数时,foreach循环将立即继续,因为超时是异步的,将params.table设置为下一个表。这将持续到foreach循环结束,其中params.table设置为数组中的最后一个值。
因此,当所有超时的回调发生时,foreach函数已经完成,并且所有回调都将打印相同的值。
答案 1 :(得分:0)
将你的params变量放在forEach的范围内:
console.log('[1] Connected to hana-database');
neededTables.forEach(function(table) {
var params = {};
params.table = table;
console.log("Checking table: " + params.table.name);
checkForTable.bind(null, params)();
});
答案 2 :(得分:0)
您正在为每个函数调用重用相同的params
对象。所以他们都看到了它的最新更新。
简单修复 - 为每个函数调用创建一个新的params
对象
neededTables.forEach(function(table) {
params = {};
params.table = table;
console.log("Checking table: " + params.table.name);
checkForTable.bind(null, params)();
});
更好的是,由于您未在params
范围之外使用forEach
,请将其移至那里。
neededTables.forEach(function(table) {
var params = { table: table };
console.log("Checking table: " + params.table.name);
checkForTable.bind(null, params)();
});
然后,因为您只设置了params
的一个属性,只需直接使用它即可。
neededTables.forEach(function(table) {
console.log("Checking table: " + table.name);
checkForTable.bind(null, table)();
});