Node.js只使用数组中的最后一项

Hi fellow Javascript / Node.js-Developer,

我遇到了一个很好的老问题与asynchronousJavaScript给我只有最后一个数组的项目(见这里和这里 )。 不幸的是,所提供的解决scheme都不适合我。

我在节点版本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! 

我完全难住。 希望有人

您正在为每个函数调用重复使用相同的params对象。 所以他们都看到最新的更新。

简单的修复 – 为每个函数调用创build一个新的params对象

 neededTables.forEach(function(table) { params = {}; params.table = table; console.log("Checking table: " + params.table.name); checkForTable.bind(null, params)(); }); 

更好的是,因为您不使用forEach范围之外的params ,请将其移动到那里。

 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)(); }); 

在这个代码中:

 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循环会立即继续,因为超时是asynchronous的,将params.table设置到下一个表。 这将持续到foreach循环结束,其中params.table被设置为数组中的最后一个值。

所以当所有超时的callback发生时,foreach函数已经完成了,所有的callback函数都会打印出相同的值。

把你的paramsvariables放在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)(); });