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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:52:54