Node/Expressjs跨控制器调用GET方法返回undefined问题咨询
问题原因及解决方案
问题根因
- 你仅对控制器方法做了赋值操作,没有实际执行该函数:此时
controllerSrcGET是函数本身,而非函数执行后的返回值,自然无法读取到返回对象的_id属性,也不会触发接口请求链路,Morgan自然不会打印请求日志。 - 控制器的接口处理方法默认设计为接收HTTP请求的中间件函数,依赖
req、res、next三个入参,即使直接调用函数如果没有传入符合要求的参数,也无法正常返回数据。 - 大部分接口处理逻辑是异步的,即使正确调用函数,直接同步读取返回值也只能拿到Promise对象而非实际结果。
解决方案
方案1(推荐):抽离公共逻辑复用
不要直接跨控制器调用接口方法,将controllerSrc.get中可复用的业务逻辑抽离为独立的服务函数,两个控制器都引入该服务使用即可,示例如下:
- 新建公共服务文件
src/service/commonService.js
// 把原controllerSrc.get中获取数据的逻辑移到这里 async function getTargetData(params) { // 原业务逻辑,比如查询数据库、处理数据 return data } module.exports = { getTargetData }
- 两个控制器分别引入服务调用即可:
// controllerSrc和controllerTgt中都可以这么用 const { getTargetData } = require('src/service/commonService') // 异步调用拿结果 const data = await getTargetData(参数) console.log(data._id)
方案2:直接调用控制器方法(不推荐)
如果不想抽离逻辑,需要模拟符合要求的req、res参数传入控制器方法,同时处理异步逻辑,示例(Express框架场景):
const controllerSrc = require('controllerSrc') // 模拟请求对象,按需填充query、params等需要的参数 const mockReq = { query: {}, params: {} } let result // 模拟响应对象,捕获接口返回的JSON数据 const mockRes = { json: (data) => { result = data } } // 调用控制器方法,异步方法要加await await controllerSrc.get(mockReq, mockRes) // 此时才能拿到返回结果 console.log(result._id)
方案3:发起HTTP请求调用接口
如果你需要走完整的HTTP请求链路(让Morgan打印日志),不要导入控制器直接调用,而是用HTTP客户端发起GET请求:
const axios = require('axios') // 替换为你的接口实际地址 const res = await axios.get('http://xxx/你的接口路径') console.log(res.data._id)
内容的提问来源于stack exchange,提问作者user16241255
相关产品推荐
相关产品推荐

