将变量传递给Node.js中的回调

Dan*_*ies 9 javascript global node.js

我对节点很新,我正在尝试创建一些获取服务器信息的东西.但这是我的问题.我设置了一个配置对象(这将及时,由发生的事件动态更新),然后在函数中,我尝试访问该对象中的值.(见下面的代码)

首先,我设置我的变量:

var util            = require('util'),
    child           = require('child_process'),
    config          = {};
Run Code Online (Sandbox Code Playgroud)

哪个工作正常.然后我加载我的配置:

function loadConfig( )
{
    // Add some code for auto-loading of args
    config = {
        "daemons": [
            ["Apache", "apache2"],
            ["MySQL",  "mysqld"],
            ["SSH", "sshd"]
        ]
    };
}
Run Code Online (Sandbox Code Playgroud)

并初始化调用该函数

loadConfig();
Run Code Online (Sandbox Code Playgroud)

之后,我对守护进程进行检查.

function getDaemonStatus( )
{
    for(var i=0; i<config.daemons.length; i++)
    {

        child.exec( 'ps ax -o \'%c %P\' | awk \'{if (($2 == 1) && ($1 == "\'' +
            config.daemons[i][1] + '\'")) print $0}\'',
            function( error, stdout, stderr )
        {

            console.log(config.daemons[i]);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到的回应是:

undefined
undefined
undefined
Run Code Online (Sandbox Code Playgroud)

我真的不想使用GLOBAL变量,所以你们想到另一种方法来解决我的问题吗?

谢谢!=]

log*_*yth 13

由于执行的异步排序,这是很多人遇到的问题.

您的for循环将从0-3开始,然后当'i'为4时退出,显然.这里要记住的难点是你的exec回调不会立即运行.仅在进程启动后运行,并且在发生时,for循环将完成.

这意味着,基本上,你的回调函数运行的所有三次,你基本上是这样做的:

console.log(config.daemons[4]);
Run Code Online (Sandbox Code Playgroud)

这就是它打印'undefined'的原因.

您需要通过将循环内容包装在匿名的自执行函数中来捕获新范围中的"i"值.

function getDaemonStatus( ) {
    for(var i=0; i<config.daemons.length; i++) {
        (function(i) {

             child.exec( 'ps ax -o \'%c %P\' | awk \'{if (($2 == 1) && ($1 == "\'' +
                config.daemons[i][1] + '\'")) print $0}\'',
                function( error, stdout, stderr ) {

                console.log(config.daemons[i]);
            });

        })(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

另外,我看到你的函数被称为'getDaemonStatus'.请记住,因为该exec回调是异步的,这也意味着您无法收集每个回调的结果,然后从getDaemonStatus返回它们.相反,您需要传递一个自己的回调,并从您的exec回调中调用它.

更新

但请注意,每次迭代使用范围的最简单方法是使用forEach,例如

function getDaemonStatus( ) {
    config.daemons.forEach(function(daemon, i){
         child.exec( 'ps ax -o \'%c %P\' | awk \'{if (($2 == 1) && ($1 == "\'' +
            daemon[1] + '\'")) print $0}\'',
            function( error, stdout, stderr ) {

            console.log(daemon);
        });
    }
}
Run Code Online (Sandbox Code Playgroud)