如何用async/await实现与.then()效率一致的批量IP异步ping检测
如何用async/await实现与.then()效率一致的批量IP异步ping检测
嘿,我完全懂你的困扰!你现在碰到的核心问题其实是串行 vs 并行的区别:
- 如果你在嵌套for循环里直接用
await ping.promise.probe(...),代码会变成串行执行——必须等当前这个ping请求完全结束,才会发起下一个,总耗时是所有ping时间的总和,自然慢得离谱; - 而你用
.then()的写法时,所有ping请求是同时触发的,它们并行执行,总耗时差不多等于最慢的那个ping请求的时间,所以速度快很多。
要想用async/await达到和.then()一样的效率,关键是要把所有ping任务先收集起来,再用Promise.all()让它们并行执行,具体代码如下:
(async function sendPing(hosts, controlList) { // 第一步:收集所有ping任务的Promise(调用probe时就已经开始执行ping了) const pingTasks = []; for (const host of hosts) { for (const clist of controlList) { const fullIp = `${host.block}.${clist.end}`; pingTasks.push(ping.promise.probe(fullIp)); } } // 第二步:等待所有并行的ping任务完成 const pingResults = await Promise.all(pingTasks); // 第三步:遍历结果输出 pingResults.forEach(result => { console.log(result.inputHost, result.alive); }); })(hosts, controlList);
为什么这样写效率和.then()一致?
当你调用ping.promise.probe(fullIp)时,ping请求已经立刻发起了,我们只是把返回的Promise对象存进数组里,并没有等待它完成。等所有任务都添加到数组后,用await Promise.all(pingTasks)一次性等待所有任务结束,这就和你用.then()时的并行逻辑完全一样了。
进阶:处理个别ping失败的情况
如果担心某个IP ping超时或失败会导致Promise.all()直接抛出错误、中断整个流程,可以改用Promise.allSettled(),这样不管成功失败都能拿到所有结果:
(async function sendPing(hosts, controlList) { const pingTasks = []; for (const host of hosts) { for (const clist of controlList) { const fullIp = `${host.block}.${clist.end}`; pingTasks.push(ping.promise.probe(fullIp)); } } // 用allSettled确保所有结果都能被捕获,不会因为单个失败中断 const pingResults = await Promise.allSettled(pingTasks); pingResults.forEach(result => { if (result.status === 'fulfilled') { const res = result.value; console.log(res.inputHost, res.alive); } else { console.error(`Ping失败: ${result.reason}`); } }); })(hosts, controlList);
这样既保留了async/await的可读性,又实现了和.then()一样的并行效率,完美解决你的问题~
备注:内容来源于stack exchange,提问作者Rıfat Tolga Kiran
相关产品推荐
相关产品推荐

