MST

星途 面试题库

面试题:TypeScript状态机与泛型结合的复杂建模

使用TypeScript创建一个通用的状态机框架,该框架可以处理任意数量的状态和状态转换。要求状态机支持异步操作,并且能够在状态转换时执行副作用函数。状态和转换的定义通过泛型来实现,使得不同业务场景可以复用该框架。请详细阐述设计思路,并给出完整的TypeScript代码实现。
40.7万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义状态和转换类型:通过泛型 S 表示状态类型,E 表示事件类型。
  2. 状态机类:包含当前状态、状态转换表以及执行副作用函数的逻辑。
  3. 异步操作支持:使用 asyncawait 来处理异步副作用函数。
  4. 转换表:用一个对象来存储状态转换规则,键为当前状态,值为另一个对象,其中键为事件,值为目标状态。

TypeScript 代码实现

type State<S, E> = {
    [event in E]?: S;
};

type StateMachineConfig<S, E> = {
    initialState: S;
    transitions: {
        [state in S]: State<S, E>;
    };
    onTransition?: (from: S, to: S, event: E) => Promise<void> | void;
};

class StateMachine<S, E> {
    private currentState: S;
    private transitions: {
        [state in S]: State<S, E>;
    };
    private onTransition?: (from: S, to: S, event: E) => Promise<void> | void;

    constructor(config: StateMachineConfig<S, E>) {
        this.currentState = config.initialState;
        this.transitions = config.transitions;
        this.onTransition = config.onTransition;
    }

    public getCurrentState(): S {
        return this.currentState;
    }

    public async transition(event: E): Promise<void> {
        const nextState = this.transitions[this.currentState]?.[event];
        if (!nextState) {
            throw new Error(`Invalid transition from ${this.currentState} on event ${event}`);
        }
        if (this.onTransition) {
            await this.onTransition(this.currentState, nextState, event);
        }
        this.currentState = nextState;
    }
}

使用示例

// 定义状态和事件类型
type UserState = 'loggedOut' | 'loggedIn';
type UserEvent = 'login' | 'logout';

// 配置状态机
const userStateMachineConfig: StateMachineConfig<UserState, UserEvent> = {
    initialState: 'loggedOut',
    transitions: {
        loggedOut: {
            login: 'loggedIn'
        },
        loggedIn: {
            logout: 'loggedOut'
        }
    },
    onTransition: async (from, to, event) => {
        console.log(`Transitioning from ${from} to ${to} on event ${event}`);
        // 模拟异步操作
        await new Promise(resolve => setTimeout(resolve, 1000));
    }
};

// 创建状态机实例
const userStateMachine = new StateMachine(userStateMachineConfig);

// 使用状态机
userStateMachine.transition('login').then(() => {
    console.log('Current state:', userStateMachine.getCurrentState());
    return userStateMachine.transition('logout');
}).then(() => {
    console.log('Current state:', userStateMachine.getCurrentState());
});