Перейти к содержанию

Конечные состояния

В диаграммах состояний вы можете объявить состояние как конечное состояние (final state). Конечное состояние указывает, что его родительское состояние «выполнено».

API

Чтобы указать, что узел состояния является конечным, установите для его свойства type значение final:

const lightMachine = createMachine({
  id: 'light',
  initial: 'green',
  states: {
    green: {
      on: {
        TIMER: { target: 'yellow' },
      },
    },
    yellow: {
      on: {
        TIMER: { target: 'red' },
      },
    },
    red: {
      type: 'parallel',
      states: {
        crosswalkNorth: {
          initial: 'walk',
          states: {
            walk: {
              on: {
                PED_WAIT: { target: 'wait' },
              },
            },
            wait: {
              on: {
                PED_STOP: { target: 'stop' },
              },
            },
            stop: {
              // 'stop' is a final state node for 'crosswalkNorth'
              type: 'final',
            },
          },
          onDone: {
            actions: 'stopCrosswalkNorth',
          },
        },
        crosswalkEast: {
          initial: 'walk',
          states: {
            walk: {
              on: {
                PED_WAIT: { target: 'wait' },
              },
            },
            wait: {
              on: {
                PED_STOP: { target: 'stop' },
              },
            },
            stop: {
              type: 'final',
            },
          },
          onDone: {
            // 'stop' is a final state node for 'crosswalkEast'
            actions: 'stopCrosswalkEast',
          },
        },
      },
      onDone: 'green',
    },
  },
});

В составном состоянии достижение конечного дочернего узла состояния (с {type: 'final'}) вызовет внутреннее событие done(...) для этого узла составного состояния (например, done.state.light.crosswalkEast) . Использование onDone эквивалентно определению перехода для этого события.

Паралельные состояния

Когда каждый дочерний узел состояния в узле параллельного состояния завершен, родительский узел параллельного состояния также становится завершенным. Когда достигается каждый узел конечного состояния в каждом дочернем составном узле, для узла параллельного состояния возникает событие done(...).

Это очень полезно при моделировании параллельных задач. Например, ниже показан торговый автомат, где пользователь и товары представляют две параллельные задачи состояния корзины:

const shoppingMachine = createMachine({
  id: 'shopping',
  initial: 'cart',
  states: {
    cart: {
      type: 'parallel',
      states: {
        user: {
          initial: 'pending',
          states: {
            pending: {
              entry: 'getUser',
              on: {
                RESOLVE_USER: { target: 'success' },
                REJECT_USER: { target: 'failure' },
              },
            },
            success: { type: 'final' },
            failure: {},
          },
        },
        items: {
          initial: 'pending',
          states: {
            pending: {
              entry: 'getItems',
              on: {
                RESOLVE_ITEMS: { target: 'success' },
                REJECT_ITEMS: { target: 'failure' },
              },
            },
            success: { type: 'final' },
            failure: {},
          },
        },
      },
      onDone: 'confirm',
    },
    confirm: {
      // ...
    },
  },
});

Переход onDone будет иметь место только тогда, когда все дочерние состояния 'cart' (например, 'user' и 'items') находятся в своих конечных состояниях. В случае с автоматом для покупок, как только будут достигнуты узлы состояний shopping.cart.user.success и shopping.cart.items.success, автомат перейдет из состояния 'cart' в состояние 'confirm'.

Внимание

Переход onDone не может быть определен на корневом узле машины. Это связано с тем, что onDone - это переход к событию done.state.*, И когда машина достигает своего конечного состояния, она больше не может принимать какие-либо события.

Примечания

  • Узел конечного состояния указывает только на то, что его непосредственный родитель готов. Это не влияет на статус выполнения каких-либо вышестоящих родителей, за исключением узлов параллельного состояния, которые выполняются, когда завершены все его дочерние узлы составного состояния.
  • Параллельное состояние, достигающее конечного подсостояния, не прекращает получать события, пока не будут выполнены все его одноуровневые состояния. Из последнего подсостояния все еще можно выйти с помощью события.
  • Узлы конечного состояния не могут иметь потомков. Это узлы атомарного состояния.
  • Вы можете указать действия входа и выхода на узлах конечного состояния.