在 express 中,函数柯里化通常用于创建可复用的中间件工厂或路由处理器。核心做法是定义一个外层函数接收配置参数,返回一个符合 (req, res, next) => void 签名的内层函数。这样可以将通用的逻辑(如权限校验、日志记录)与具体的业务处理解耦,通过传入不同的配置生成特定的中间件实例。

如何构建带配置的通用中间件
要构建带配置的通用中间件,需要编写一个接受配置对象并返回中间件函数的工厂模式。这种结构允许在注册路由时动态注入行为,例如根据用户角色决定访问权限。关键在于返回的函数必须严格遵循 Express 中间件的签名规范,并在内部闭包中捕获外部传入的配置数据。

const express = require('express');
const app = express();
// 柯里化中间件工厂:接收配置,返回中间件
function authMiddleware(config) {
const { requiredRole } = config;
// 返回实际的中间件函数
return function (req, res, next) {
const userRole = req.headers['x-role'] || 'guest';
if (userRole === requiredRole) {
next();
} else {
res.status(403).json({ error: `Access denied. Required: ${requiredRole}` });
}
};
}
// 使用柯里化生成的中间件
app.get('/admin', authMiddleware({ requiredRole: 'admin' }), (req, res) => {
res.json({ message: 'Welcome admin' });
});
app.get('/user', authMiddleware({ requiredRole: 'user' }), (req, res) => {
res.json({ message: 'Welcome user' });
});
console.log('Server configured with curried middleware');
上述代码展示了如何通过 authMiddleware 工厂函数生成两个不同权限要求的中间件实例。当请求到达时,Express 会调用返回的内层函数,该函数利用闭包访问 requiredRole 进行判断。这种方式避免了在每个路由中重复编写权限检查逻辑,提高了代码的可维护性。
如何在路由处理中复用状态管理逻辑
在路由处理中复用状态管理逻辑时,可以利用柯里化将数据库连接或上下文对象预先绑定到处理函数上。这种做法使得路由处理器只关注业务逻辑,而无需关心数据源的初始化细节。通过将环境配置或依赖项作为参数传入,可以生成针对不同环境(如测试、生产)的专用处理器。

const express = require('express');
const app = express();
// 模拟数据库服务
const dbService = {
findById: async (id) => ({ id, name: 'Test User' })
};
// 柯里化路由处理器工厂:接收依赖,返回处理器
function createUserHandler(dependencies) {
const { db } = dependencies;
return async (req, res) => {
try {
const user = await db.findById(req.params.id);
res.json(user);
} catch (err) {
res.status(500).json({ error: 'Database error' });
}
};
}
// 绑定依赖并注册路由
const handleUser = createUserHandler({ db: dbService });
app.get('/users/:id', handleUser);
console.log('Route handler bound with dependencies');
在这个示例中,createUserHandler 函数接收 dbService 作为参数,并返回一个异步处理函数。这个返回的函数直接使用了闭包中的 db 对象,从而实现了依赖注入。这种模式不仅简化了路由定义的语法,还使得单元测试变得更加容易,因为可以在测试时传入模拟的依赖对象。通过这种方式,开发者可以将复杂的初始化逻辑从路由定义中剥离出来,保持代码的清晰和模块化。
基于中间件工厂返回值的类型检查问题
当中间件工厂返回的函数未正确调用 next() 或未发送响应时,Express 会抛出错误。这是因为 Express 要求每个中间件要么传递控制权给下一个中间件,要么结束请求-响应周期。如果柯里化后的内部逻辑遗漏了这两种情况之一,程序将进入未定义状态。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











