如何在for of循环的嵌套异步回调中返回含对象的数组?
解决node-cmd异步时序问题,获取完整http-ping结果数组
你的问题核心是node-cmd的run方法是异步回调模式,循环里的回调函数还没执行完(http-ping命令还没跑完),外面的console.log(results)就已经执行了,所以拿到的是空数组。而循环内打印会重复,是因为每个回调完成时都会执行一次打印,每次push后数组长度增加,所以会输出多次不同状态的数组。
要解决这个问题,最好的方式是把异步回调转换成Promise,再用Promise.all等待所有任务完成:
var cmd = require('node-cmd'); const hosts = [ 'https://adressone.com', 'https://adresstwo.com', 'https://adressthree.com', 'https://adressfour.com' ]; // 把cmd.run包装成Promise function pingHost(host) { return new Promise((resolve, reject) => { cmd.run(`http-ping.exe ${host}`, (err, data, stderr) => { if (err || stderr) { // 处理错误,比如服务器宕机的情况 resolve({ host: host, status: 'error', bytes: '-', time: '-' }); return; } const result = data.split('>'); const resultDig = result[1].replace(/[^0-9\.]+/g, " ").replace(/2$/g, "").trim().split(' ') resolve({ host: host, status: resultDig[0], bytes: resultDig[1], time: resultDig[2], }); }); }); } // 用Promise.all等待所有ping任务完成 async function getAllResults() { const results = await Promise.all(hosts.map(host => pingHost(host))); console.log(results); } getAllResults();
关键说明:
- Promise封装:把每个
cmd.run调用包装成Promise,这样可以用await等待单个任务完成,也能统一处理成功/失败情况。 - Promise.all:一次性发起所有ping请求,等待所有任务都完成后,再收集结果数组,此时打印的就是完整的结果集合。
- 错误处理:新增了错误分支,当http-ping执行失败(比如服务器宕机)时,会返回带错误标记的对象,避免整个流程卡住。
执行这段代码后,console.log(results)会输出你期望的完整数组:
[{ host: 'https://adressone.com', status: '200', bytes: '703', time: '640' }, { host: 'https://adresstwo.com', status: '200', bytes: '703', time: '640' }, { host: 'https://adressthree.com', status: '200', bytes: '703', time: '640' }, { host: 'https://adressfour.com', status: '200', bytes: '703', time: '640' } ]
内容的提问来源于stack exchange,提问作者ValleP
相关产品推荐
相关产品推荐

