NodeJS如何等待所有url-exists执行完毕后再返回接口响应
问题根因
你使用的url-exists库默认是回调风格的异步API,无法被await识别。代码执行到urlExists()时只会把回调函数提交给事件循环,不会等待回调执行完成就会继续往下执行后续逻辑,因此会提前返回还没填充数据的空docs数组。
解决方案
先将回调式的urlExists包装为返回Promise的版本,再等待所有URL检查任务全部执行完成后再返回结果。
完整修改后代码
// 引入util模块的promisify工具 const { promisify } = require('util'); // 将回调风格的urlExists转为支持await的Promise版本 const urlExists = promisify(require('url-exists')); const ESAPI = require('node-esapi'); exports.getDocs = async (req, res, next) => { try { const id = req.params.tID; const getDocs = await models.Documents.getDocs(id); // 从数据库获取数据 // 构造所有URL检查的异步任务数组 const checkTasks = getDocs.map(async d => { const docName = ESAPI.encoder().encodeForHTML(d.DocumentName); const path = `https://mywebsite/Files/${id}/${docName}`; const exists = await urlExists(path); return exists ? { path, audited: d.Audited, comment: d.Comment } : null; }); // 等待所有检查任务执行完成 const taskResults = await Promise.all(checkTasks); // 过滤掉URL不存在的无效条目,得到最终结果 const docs = taskResults.filter(Boolean); console.log(docs); return res.json(docs); } catch(err) { return res.json([]); } }
修改点说明
- 用Node.js内置的
util.promisify转换异步API风格,适配async/await语法 - 采用
Promise.all并行执行所有URL检查任务,相比串行等待性能更高,适合IO密集型的校验场景 - 所有任务执行完成后再过滤生成最终返回数组,确保响应时所有校验逻辑已执行完毕
- 如果需要控制请求频率避免被目标站点拦截,可将并行逻辑改为
for...of循环内逐个await执行检查任务即可
内容的提问来源于stack exchange,提问作者myTest532 myTest532
相关产品推荐
相关产品推荐

