You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取嵌套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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:39:04