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

时间:2014-01-29 09:48:47

标签: javascript arrays node.js asynchronous

你好Javascript / Node.js-Developer,

我遇到了异步Javascript的老问题,只给我一个数组的最后一项(如HEREHERE所示)。不幸的是,所提供的解决方案都不适合我。

我在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!

我完全难过了。希望有人

3 个答案:

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