如何绕过异步Node.js行为?

Mat*_*ful 0 javascript asynchronous node.js

我正在编写一个ping网站的脚本,并在Web UI中返回结果.但是,我遇到了一个问题,我正试图找出最佳解决方案.

这段代码需要返回一个状态数组,但是由于Node.js的异步行为,它返回一个空数组,因为代码需要时间来执行.

这是我有的:

var ping = require('ping');

function checkConnection(hosts) {

    var results = [];

    hosts.forEach(function (host) {
        ping.sys.probe(host, function (isAlive) {
            results.push({"host": host, "status": isAlive});
        });
    });

    return {results: results, timestamp: new Date().getTime()};
}

module.exports.checkConnection = checkConnection;
Run Code Online (Sandbox Code Playgroud)

我知道你可以用定时器解决这个问题,但这里的简单和最理想的解决方案是什么?

T.J*_*der 5

如何绕过异步Node.js行为?

别.相反,通过接受回调或返回承诺来拥抱checkConection.

回调示例:

function checkConnection(hosts, callback) {

    var results = [];

    hosts = hosts.slice(0); // Copy
    hosts.forEach(function (host) {
        ping.sys.probe(host, function (isAlive) {
            results.push({"host": host, "status": isAlive});
            if (results.length === hosts.length) {
                callback({results: results, timestamp: new Date().getTime()});
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

注意防守浅层副本hosts.如果你不这样做,那么由于这个代码是异步运行的,调用代码可以hosts在处理响应时添加或删除数组,并且长度永远不会匹配.

另一种无需复制即可处理的方法是简单计算您已启动的请求数:

function checkConnection(hosts, callback) {

    var results = [];
    var requests = hosts.length;

    hosts.forEach(function (host) {
        ping.sys.probe(host, function (isAlive) {
            results.push({"host": host, "status": isAlive});
            if (results.length === requests) {
                callback({results: results, timestamp: new Date().getTime()});
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

看起来像它建立一个竞争条件(如果你出修改hosts设置后requests,但你做之前启动您的probe疑问?),但它没有,因为节点运行您在单个线程JavaScript,因此没有其他的代码可以达到在和行hosts之间进行修改.requests = hosts.lengthhosts.forEach