柯里化状态机分发器通过“状态→动作”两次调用实现轻量动作路由:先传状态返回预置处理器,再传动作执行逻辑;适合配置驱动、逻辑静态场景,但不适用于复杂副作用或跨状态共享动作。

用柯里化实现状态机动作分发,核心是把「状态 + 动作」的二维映射,拆成两次调用:先传状态,返回一个预置状态的动作处理器;再传动作名,执行对应逻辑。它不替代完整状态机库,但适合轻量、配置驱动、动作逻辑相对静态的场景。
1. 基础柯里化分发器:状态 → 动作 → 执行
定义一个高阶函数,接收当前状态,返回一个闭包函数,该函数接收动作类型并查表执行:
const createDispatcher = (state) => (actionType, payload) => {
const handlers = {
'idle': {
'START': () => console.log('→ starting...'),
'ERROR': (err) => console.error('Idle got error:', err)
},
'loading': {
'SUCCESS': (data) => console.log('Loaded:', data),
'FAIL': (err) => console.log('Load failed:', err),
'CANCEL': () => console.log('Loading cancelled')
},
'success': {
'RESET': () => console.log('Reset to idle')
}
};
const handler = handlers[state]?.[actionType];
return handler ? handler(payload) : console.warn(`No handler for ${state}.${actionType}`);
};
// 使用
const dispatchInLoading = createDispatcher('loading');
dispatchInLoading('SUCCESS', { id: 123 }); // Loaded: {id: 123}
dispatchInLoading('FAIL', 'network timeout'); // Load failed: network timeout
2. 支持动态注册与组合:增强可维护性
硬编码分支不易扩展。可改用可注册的 dispatcher,并利用柯里化保持状态上下文:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
class StateDispatcher {
constructor() {
this.handlers = new Map(); // state → Map<action handler>
}
on(state, action, handler) {
if (!this.handlers.has(state)) {
this.handlers.set(state, new Map());
}
this.handlers.get(state).set(action, handler);
}
// 柯里化入口:固定状态,返回动作分发函数
for(state) {
return (action, payload) => {
const stateMap = this.handlers.get(state);
const handler = stateMap?.get(action);
return handler ? handler(payload) : undefined;
};
}
}
// 使用
const dispatcher = new StateDispatcher();
dispatcher.on('idle', 'START', () => console.log('Go!'));
dispatcher.on('loading', 'SUCCESS', (data) => console.log('Done:', data));
const dispatchIdle = dispatcher.for('idle');
dispatchIdle('START'); // Go!
const dispatchLoading = dispatcher.for('loading');
dispatchLoading('SUCCESS', { ok: true }); // Done: {ok: true}
</action>
3. 结合 reducer 模式:返回新状态(纯函数风格)
若状态机需驱动 UI 或配合 Redux-like 流程,柯里化可封装 reducer 调用:
const createReducerDispatcher = (reducer) => (state) => (action) =>
reducer(state, action);
// 示例 reducer
const authReducer = (state, action) => {
switch (state) {
case 'unauthorized':
return action.type === 'LOGIN' ? 'authenticating' : state;
case 'authenticating':
return action.type === 'LOGIN_SUCCESS' ? 'authorized' :
action.type === 'LOGIN_FAIL' ? 'unauthorized' : state;
default:
return state;
}
};
// 柯里化使用
const dispatchAuth = createReducerDispatcher(authReducer);
const next = dispatchAuth('unauthorized');
console.log(next({ type: 'LOGIN' })); // 'authenticating'
console.log(next({ type: 'LOGOUT' })); // 'unauthorized'
4. 实际建议与边界注意
柯里化分发适合明确、有限的状态/动作组合。不适合以下情况:
- 状态转移逻辑复杂且依赖副作用(如异步校验、多步骤协调),应交由状态机库(XState)或自定义 runloop 处理
- 动作需跨状态共享逻辑(如所有状态都响应 'LOGOUT'),柯里化绑定单一状态会重复注册,此时更适合全局 action 中间件 + 状态路由
- 需要可视化、时序调试、历史回溯等能力,纯柯里化无元信息支撑
它真正价值在于:让状态上下文显式、不可变地流经调用链,减少 this 或闭包误用,提升测试隔离性——比如每个 dispatchInLoading 都是独立、无共享状态的纯函数。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










