柯里化不直接校验路由权限,但能优雅构建可复用、可组合、按序执行的权限检查函数链;它通过预设参数封装单个校验逻辑,再经pipe或asyncPipe串联执行,支持同步/异步校验及元信息动态调度。

函数柯里化本身不直接参与路由权限校验,但它能帮你优雅地构建**可复用、可组合、按顺序执行的权限检查函数链**。在前端路由拦截(比如 Vue Router 的 beforeEach 或 React Router 的 loader/element 保护)中,真正起作用的是「按顺序执行多个校验逻辑,并在任一失败时中断」——而柯里化是组织这类逻辑的利器之一。
用柯里化封装单个权限检查器
把每个权限判断逻辑(如“是否登录”、“是否有角色”、“是否在白名单”)写成一个接收必要参数、返回布尔值或 Promise 的函数。再用柯里化让它支持预设部分参数,便于复用:
// 柯里化版:检查用户角色是否匹配 const hasRole = (requiredRoles) => (user) => user && user.roles && requiredRoles.some(r => user.roles.includes(r)); // 使用时预设权限要求,得到具体校验函数 const canAccessAdmin = hasRole(['admin', 'super_admin']); const canEditPost = hasRole(['editor', 'admin']);
组合多个柯里化校验函数形成校验链
借助函数组合(如 pipe 或手写串联),让多个柯里化后的校验函数按顺序执行,任意一个返回 false 或抛出错误就终止:
// 简易 pipe:从左到右执行,短路失败
const pipe = (...fns) => (arg) =>
fns.reduce((acc, fn) => acc === false ? false : fn(acc), arg);
// 组合校验逻辑:登录检查 → 角色检查 → 数据级权限(如资源所属)
const checkRoutePermission = pipe(
isLoggedIn, // (to, from, next) => user || false
(user) => hasRole(['admin'])(user),
(user) => canAccessResource(user, to.meta.resourceId)
);
// 在路由守卫中使用
router.beforeEach((to, from, next) => {
const result = checkRoutePermission({ to, from, next });
if (result === false) return next('/403');
next();
});
配合异步校验(如接口鉴权)做柯里化 + Promise 链
若某项权限需请求后端(如「用户是否有该菜单权限」),把异步函数也柯里化,再用 async/await 或 Promise.allSettled 控制顺序和中断:
// 柯里化异步检查:传入 API 函数和权限码,返回待执行函数
const hasPermissionApi = (api, permissionCode) => (user) =>
api({ userId: user.id, code: permissionCode })
.then(res => res.data?.allowed)
.catch(() => false);
// 组合成支持 async 的校验链(需改用 async pipe)
const asyncPipe = (...fns) => async (arg) => {
let acc = arg;
for (const fn of fns) {
acc = await fn(acc);
if (acc === false) break;
}
return acc;
};
const fullCheck = asyncPipe(
fetchUser, // 返回 user
(user) => hasRole(['admin'])(user),
(user) => hasPermissionApi(checkMenuApi, to.meta.permission)(user)
);
实际集成到路由元信息中更灵活
把柯里化后的校验函数名或配置挂到 route.meta 上,守卫统一调度,避免硬编码逻辑:
// 定义路由时声明所需权限
{
path: '/dashboard',
component: Dashboard,
meta: {
permissions: [
{ type: 'role', value: ['admin'] },
{ type: 'api', api: checkMenuApi, code: 'dashboard_view' }
]
}
}
// 守卫中动态生成并执行校验链
router.beforeEach(async (to, from, next) => {
const checks = to.meta.permissions?.map(p => {
if (p.type === 'role') return hasRole(p.value);
if (p.type === 'api') return hasPermissionApi(p.api, p.code);
}) || [];
const result = await asyncPipe(...checks)(currentUser);
if (!result) return next('/403');
next();
});
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











