Действия¶
Действия (actions) — это эффект запустил и забыл». Их можно объявить тремя способами:
entry
действия выполняются при входе в состояниеexit
действия выполняются при выходе из состояния- действия перехода выполняются при переходе
API¶
Действия могут быть добавлены так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
|
Когда мне следует использовать переход (transition),
а когда - входные и выходные действия (action)?
Они означают разные вещи:
Действие входа или выхода означает «выполнить это действие при любом переходе, который входит или выходит из этого состояния». Используйте действия входа или выхода, когда само действие зависит только от узла состояния, в котором оно находится, а не от узлов или событий предыдущего или следующего состояния.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Действие перехода означает «выполнить это действие только на этом переходе». Используйте действия перехода, когда действие зависит от события и узла состояния, в котором оно находится в данный момент.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
Подсказка
Реализации действий можно быстро прототипировать, указав функцию действия непосредственно в конфигурации автомата:
1 2 3 4 5 6 |
|
Реорганизация встроенных реализаций действий в свойстве actions
параметров автомата упрощает отладку, сериализацию, тестирование и точную визуализацию действий.
Декларативные действия¶
Экземпляр State
, возвращаемый из machine.transition(...)
, имеет свойство .actions
, которое представляет собой массив объектов действия для выполнения интерпретатором:
1 2 3 4 5 6 7 8 9 10 11 |
|
Каждый объект действия имеет два свойства (и другие, которые вы можете указать):
type
— тип действияexec
— реализация функции действия
Функция exec
принимает три параметра:
Параметр | Тип | Описание |
---|---|---|
context | TContext | Текущий контекст автомата |
event | event object | Событие, вызвавшее переход |
actionMeta | meta object | Объект, содержащий метаданные о действии |
Объект actionMeta
включает следующие свойства:
Свойство | Тип | Описание |
---|---|---|
action | action object | Исходный объект действия |
state | State | Разрешенное состояние автомата после перехода |
Интерпретатор вызовет функцию exec
с currentState.context
, event
и state
, в которое перешел автомат. Вы можете настроить это поведение. Подробнее читайте в разделе «Выполнение действий».
Порядок действий¶
При интерпретации диаграмм состояний порядок действий не обязательно имеет значение (то есть они не должны зависеть друг от друга). Однако порядок действий в массиве state.actions
:
exit
— все действия выхода узла (ов) вышедшего состояния, от узла атомарного состояния вверхactions
— все действия перехода, определенные на выбранном переходеentry
— все действия входа узла (ов) введенного состояния, от родительского состояния вниз
Внимание
В XState версии 4.x назначенные действия assign
имеют приоритет и выполняются перед любыми другими действиями. Это поведение будет исправлено в версии 5, так как действия назначения будут вызываться по порядку.
Осторожно
Все создатели действий, описанные здесь, возвращают объекты действий; это чистая функция, которая возвращает только объект действия и не обязательно отправляет событие. Не вызывайте создателей действий самостоятельно — они ничего не сделают!
1 2 3 4 5 6 7 8 9 10 11 |
|
Действие send()¶
Создатель действия send(action)
создает специальный объект действия send
, который сообщает службе (т. е. интерпретируемому автомату) отправить это событие самому себе. Он ставит событие в очередь работающей службы во внешней очереди событий, что означает, что событие отправляется на следующем «шаге» интерпретатора.
Параметр | Тип | Описание |
---|---|---|
event | string event object event expression | Событие для отправки в указанные options.to (или себе) |
options? | send options | Параметры отправки события |
Параметр отправки options
— это объект, содержащий:
Свойство | Тип | Описание |
---|---|---|
id? | string | Идентификатор отправки (используется для отмены) |
to? | string | Цель события (по умолчанию self ) |
delay? | number | Тайм-аут (миллисекунды) перед отправкой события, если событие не отменено до истечения тайм-аута. |
Внимание
Функция send(...)
является создателем действия; это чистая функция, которая возвращает только объект действия и не обязательно отправляет событие.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
|
Аргумент события event
, переданный в send(event)
, может быть:
- Строковое событие, например
send('TOGGLE')
- Объект события, например
send({type: 'TOGGLE', payload: ...})
- Выражение события, которое представляет собой функцию, которая принимает текущий контекст
context
и событиеevent
, вызвавшее действиеsend()
, и возвращает объект события:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Цели отправки¶
Событие, отправленное создателем действия send(...)
, может означать, что оно должно быть отправлено определенным целям, таким как вызванные службы или порожденные акторы. Это делается путем указания свойства {to: ...}
в действии send (...)
:
1 2 3 4 5 6 7 8 9 |
|
Цель в свойстве to
также может быть целевым выражением (target expression), которое представляет собой функцию, принимающую текущий контекст context
и событие event
, вызвавшее действие, и возвращает либо строковую цель, либо ссылку на актора:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Внимание
Опять же, функция send(...)
является создателем действия и не обязательно отправляет событие. Вместо этого она возвращает объект действия, который описывает, куда будет отправлено событие:
1 2 3 4 5 6 7 8 9 |
|
Чтобы отправить событие с дочернего автомата в родительский, используйте sendParent(event)
(принимает те же аргументы, что и send(...)
).
Действие raise()¶
Создатель действия raise()
ставит событие в очередь на диаграмму состояний во внутренней очереди событий. Это означает, что событие отправляется немедленно на текущем «шаге» интерпретатора.
Параметр | Тип | Описание |
---|---|---|
event | string event object | Событие, которое нужно поднять. |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
|
Кликните оба события STEP
и RAISE
в визуализаторе, чтобы увидеть разницу.
Действие respond()
¶
Начиная с версии 4.7+
respond()
создает действие send()
, которое отправляется в службу, отправившую событие.
При этом используются внутренние события SCXML, чтобы получить origin
из события и установить to
для действия send()
.
Параметр | Тип | Описание |
---|---|---|
event | string event object send expression | Событие, которое нужно отправить обратно отправителю |
options? | send options object | Параметры для передачи в событие send() |
Пример использования действия respond()
Пример демонстрирует, как некоторая родительская служба (authClientMachine
) отправляет событие 'CODE'
в вызываемую authServerMachine
, а authServerMachine
отвечает событием 'TOKEN'
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|
См. 📖 Отправка ответов для более подробной информации.
Действие forwardTo()
¶
Начиная с версии 4.7+
forwardTo()
создает действие send()
, которое перенаправляет самое последнее событие указанной службе через его идентификатор.
Параметр | Тип | Описание |
---|---|---|
target | string or function that returns service | Целевая служба, в которую нужно отправить самое последнее событие. |
Пример использования действия forwardTo()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Действие escalate()¶
Начиная с версии 4.7+
escalate()
эскалирует ошибку, отправляя ее в родительский автомат. Ошибка отправляется как специальное событие, которое распознается автоматом.
Параметр | Тип | Описание |
---|---|---|
errorData | any | Данные об ошибке для передачи (отправки) родительскому автомату. |
Пример использования действия escalate()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
|
Действие log()¶
Создатель действия log()
— это декларативный способ регистрации всего, что связано с текущим контекстом состояния context
и / или событием event
. Принимает два необязательных параметра:
Параметр | Тип | Описание |
---|---|---|
expr? | string function | Строка или функция, которая принимает контекст context и событие event и возвращает значение для логирования. |
label? | string | Метка для обозначения залогированного сообщения message |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
|
Без параметров log()
— это действие, которое регистрирует объект со свойствами context
и event
, содержащими текущий контекст и инициирующее событие.
Действие choose()¶
choose()
создает действие, которое указывает, какие действия должны быть выполнены на основе определенных условий.
Параметр | Тип | Описание |
---|---|---|
conds | array | Массив объектов, содержащий действия actions , которые нужно выполнить, когда заданное условие cond истинно |
Возвращает:
Специальный объект действия "xstate.choose"
, который внутренне оценивается, чтобы определить, какие объекты действия должны быть выполнены.
Каждый объект «условных действий» в cond
имеет следующие свойства:
actions
— объекты действия для выполненияcond?
— условие выполнения этих действийactions
Внимание
Не используйте choose()
для выполнения действий, которые в иначе можно определить как безусловные действия, выполняемые в определенных состояниях или переходах в entry
, exit
или actions
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
|
Это аналогично элементам SCXML <if>
, <elseif>
и <else>
: www.w3.org/TR/scxml/#if
Действие pure()¶
Создатель действия pure()
— это чистая функция (отсюда и название), которая возвращает объект(ы) действия, который должен быть выполнен, на основе контекста context
текущего состояния и события event
, вызвавшего действие. Это позволяет вам динамически определять, какие действия нужно выполнять.
Параметр | Тип | Описание |
---|---|---|
getActions | function | Функция, которая возвращает объект(ы) действия для выполнения на основе заданного context и event |
Возвращает:
Специальный объект действия «xstate.pure
», который будет внутренне оценивать свойство get
для определения объектов действия, которые нужно выполнить.
Параметры getActions(context, event)
:
Параметр | Тип | Описание |
---|---|---|
context | object | Текущий context состояния |
event | event object | Объект события, инициировавший действия. |
Возвращает:
Объект действия, массив объектов действия или undefined
, если объектов действия нет.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Действия в переходах без смены состояния¶
Переход без смены состояния (self-transition) — это когда состояние переходит в само себя, из которого оно может выйти, а затем снова войти в себя. Такие переходы могут быть внутренними или внешними:
Внутренний переход не будет завершен и повторно начат, поэтому действия входа entry
и выхода exit
узла состояния не будут выполняться заново.
- Внутренние переходы обозначаются
{internal: true}
илиtarget
какundefined
. - Действия, определенные в свойстве
actions
перехода, будут выполнены.
Внешний переход завершится и повторно войдет в себя, поэтому действия входа entry
и выхода exit
узла состояния будут выполнены снова.
- По умолчанию все переходы внешние. Чтобы задать внешний переход явно, укажите
{internal: false}
. - Действия, определенные в свойстве
actions
перехода, будут выполнены.
Например, эта счетная машина имеет одно состояние 'counting'
с внутренними и внешними переходами:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
|