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)
我知道你可以用定时器解决这个问题,但这里的简单和最理想的解决方案是什么?
如何绕过异步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