如何获取嵌套Promise数据?Express路由向Vue传参报错排查
解决Express路由中嵌套Promise数据返回的问题
咱们先从你遇到的最直接的错误入手,再梳理异步逻辑的问题,一步步把数据正确返回给Vue应用:
1. 先修复ReferenceError: data is not defined错误
看你路由里的代码:
app.get('/notification', (req, res) => { const getData = (data) => { console.log(data) } scheduler(data) // 这里的`data`根本没定义! })
你调用scheduler(data)时,data变量从来没有声明过,而且scheduler函数的参数是回调函数,不是data。所以这里应该改成把getData传进去:
scheduler(getData)
不过这只是解决了报错,咱们还要解决更核心的问题:如何把嵌套异步操作的数据正确返回给前端。
2. 重构异步逻辑:用async/await替代嵌套Promise+回调
你的代码里嵌套了太多then和自定义Promise,逻辑非常绕,而且用回调的方式很难在Express路由里统一返回数据。咱们把代码改成更清晰的async/await风格:
第一步:修改Express路由,直接等待异步结果并响应
Express路由支持async函数,咱们可以直接在路由里等待scheduler的结果,然后用res.json()把数据发送给Vue:
app.get('/notification', async (req, res) => { try { // 等待scheduler处理完所有异步操作,拿到结果 const notificationResults = await scheduler(); // 把结果返回给前端 res.json(notificationResults); } catch (error) { // 捕获错误,返回500状态码给前端 console.error('路由处理错误:', error); res.status(500).json({ message: '获取通知数据失败', error: error.message }); } })
第二步:重构scheduler函数,返回Promise并整理异步逻辑
把scheduler改成async函数,去掉回调,直接返回处理后的结果:
const scheduler = async () => { const savedNotifications = []; try { // 连接SFTP await sftp.connect({ credentials }); // 获取根目录文件列表 const fileList = await sftp.list(root); // 过滤最近5分钟内被访问的文件 const currentTime = moment(); const fiveMinutesAgo = moment().subtract(5, 'minutes'); const filteredFiles = fileList.filter(file => { const fileAccessTime = moment(file.accessTime); return fileAccessTime.isBetween(fiveMinutesAgo, currentTime); }); // 遍历每个符合条件的文件 for (const file of filteredFiles) { // 获取文件内容 const fileContent = await sftp.get(`Inbound/${file.name}`); // 把CSV内容解析成JSON(改用Promise版的解析逻辑,避免嵌套) const csvJsonData = await new Promise((resolve, reject) => { const parsedData = []; csv() .fromString(fileContent.toString()) .on('data', jsonObj => parsedData.push(jsonObj)) .on('end', () => resolve(parsedData)) .on('error', err => reject(err)); }); // 遍历CSV解析后的每个对象,保存到数据库 for (const jsonObj of csvJsonData) { const notification = new Notification(jsonObj); const savedResult = await notification.save(); savedNotifications.push(savedResult); console.log('保存成功:', savedResult); } } // 记得关闭SFTP连接,避免资源泄漏 await sftp.end(); // 返回所有保存成功的通知数据 return savedNotifications; } catch (error) { console.error('Scheduler处理错误:', error); // 抛出错误,让路由层捕获处理 throw error; } }
3. 关键修改点说明
- 去掉回调,用返回值传递结果:原来的回调方式很难在Express路由里统一返回数据,改成
async/await后,直接通过函数返回值拿到所有异步操作的结果,再用res.json()发送给前端。 - 整理嵌套逻辑:把原来嵌套在
then里的SFTP操作、CSV解析、数据库保存,拆成清晰的步骤,代码可读性大幅提升,也更容易排查问题。 - 添加错误处理:用
try/catch捕获所有异步操作的错误,路由层统一返回错误响应给前端,避免请求挂起。 - 关闭SFTP连接:操作完成后关闭连接,避免资源泄漏。
这样修改后,当你访问localhost/notification时,就能正确拿到所有保存成功的通知数据,Vue应用也能正常接收啦。
内容的提问来源于stack exchange,提问作者ads6495
相关产品推荐
相关产品推荐

