Fastify中如何访问控制器父函数内部的嵌套函数?
Fastify中无法访问控制器嵌套函数的解决方案
问题场景
在Fastify框架中,尝试在路由文件里调用控制器父函数内部嵌套的getConfig()函数时失败,当前代码结构的目的是让控制器能访问Fastify实例,现有代码如下:
route.js
import formbody from '@fastify/formbody' import controller from '../../controllers/controller.js' const routes = (fastify, options, done) => { fastify.register(formbody) fastify.register(controller) fastify.get('/get-config', (req, rep) => { getConfig(req, rep) // 此处无法访问getConfig }) } export default routes
controller.js
import merchant from '../models/merchant.js' const controller = (fastify, options, done) => { const srvcMerchant = new merchant(fastify) const getConfig = async (req, rep) => { const config = await srvcMerchant.getConfig(req.id); if (!config) { return rep .status(404) .send({ message: 'Not found' }) } rep.send(config); } } export default controller
问题原因
getConfig是controller函数内部的局部变量,作用域仅限于controller函数内部,路由文件的代码无法直接访问该函数。同时,当前通过fastify.register(controller)仅将控制器作为插件注册,未暴露内部函数供外部调用。
解决方案
方案一:控制器内部注册路由
直接在控制器中利用Fastify实例定义路由,无需跨作用域调用函数:
修改controller.js:
import merchant from '../models/merchant.js' const controller = (fastify, options, done) => { const srvcMerchant = new merchant(fastify) const getConfig = async (req, rep) => { const config = await srvcMerchant.getConfig(req.id); if (!config) { return rep .status(404) .send({ message: 'Not found' }) } rep.send(config); } // 直接在控制器内注册路由 fastify.get('/get-config', getConfig) done() // 必须调用done完成插件注册 } export default controller
route.js简化为:
import formbody from '@fastify/formbody' import controller from '../../controllers/controller.js' const routes = (fastify, options, done) => { fastify.register(formbody) fastify.register(controller) done() } export default routes
方案二:将函数挂载到Fastify实例
把getConfig挂载到Fastify实例上,路由文件通过实例访问该函数:
修改controller.js:
import merchant from '../models/merchant.js' const controller = (fastify, options, done) => { const srvcMerchant = new merchant(fastify) // 挂载到fastify实例 fastify.getConfig = async (req, rep) => { const config = await srvcMerchant.getConfig(req.id); if (!config) { return rep .status(404) .send({ message: 'Not found' }) } rep.send(config); } done() } export default controller
route.js中调用:
import formbody from '@fastify/formbody' import controller from '../../controllers/controller.js' const routes = (fastify, options, done) => { fastify.register(formbody) fastify.register(controller) fastify.get('/get-config', (req, rep) => { return fastify.getConfig(req, rep) // 需返回异步函数的Promise }) done() } export default routes
方案三:控制器返回处理函数对象
让控制器返回包含处理函数的对象,避免污染Fastify实例:
修改controller.js:
import merchant from '../models/merchant.js' // 改为接收fastify实例并返回处理函数的工厂函数 const createController = (fastify) => { const srvcMerchant = new merchant(fastify) const getConfig = async (req, rep) => { const config = await srvcMerchant.getConfig(req.id); if (!config) { return rep .status(404) .send({ message: 'Not found' }) } rep.send(config); } return { getConfig } } export default createController
route.js中使用:
import formbody from '@fastify/formbody' import createController from '../../controllers/controller.js' const routes = (fastify, options, done) => { fastify.register(formbody) // 创建控制器实例并获取getConfig const { getConfig } = createController(fastify) fastify.get('/get-config', getConfig) done() } export default routes
注意事项
- 异步处理函数需确保返回Promise或使用
async/await,Fastify会自动处理异步响应。 - 插件注册时必须调用
done(),否则Fastify会判定插件未加载完成。
内容的提问来源于stack exchange,提问作者Dally
相关产品推荐
相关产品推荐

