2014-01-29 30 views
1

喜同胞的JavaScript/Node.js的开发者,的Node.js只在阵列使用最后一个项目

我遇到好老问题与异步JavaScript给我一个数组的只有最后一项(如图HEREHERE)。不幸的是,没有提供的解决方案为我工作。

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

实际工作输出:

[1] Connected to hana-database 
Checking table: ipfix_exporters 
Checking table: ipfix_messages 
Table 'ipfix_messages' does exist! 
Table 'ipfix_messages' does exist! 

我完全难倒。希望有人

回答

0

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

简单的解决方法 - 创建一个新params对象为每个功能调用

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

更妙的是,因为你不使用paramsforEach范围,在那里将其移动。

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

请您进一步解释为什么绑定“params”不起作用,但绑定“表”做了诡计?是否因为范围而“恰好”? –

+1

因为你绑定的*同*对象的每个功能,你再改。每个'table'对象都是不同的,并且在异步函数运行之前不要更改它们。 – OrangeDog

+0

简而言之:结合(以及任何其它闭合捕获)取引用,而不是拷贝。 – OrangeDog

4

在此代码:

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

当您设置params.table,在foreach函数的每一次迭代正在更新params.table下一个表。

当你调用下面的1000毫秒超时你的函数,foreach循环将立即继续,因为超时是异步的,设置params.table到下表中。这将持续到foreach循环结束,其中params.table被设置为数组中的最后一个值。

所以,当你所有的超时的回调时,在foreach功能已经完成,所有的回调将打印相同的值。

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)(); 
}); 
相关问题