Переходы могут выполняться автоматически после задержки. Это настраивается в состоянии в свойстве after, которое задает миллисекундные задержки на переходы:
1 2 3 4 5 6 7 8 9101112131415161718192021222324
constlightDelayMachine=createMachine({id:'lightDelay',initial:'green',states:{green:{after:{// after 1 second, transition to yellow1000:{target:'yellow'},},},yellow:{after:{// after 0.5 seconds, transition to red500:{target:'red'},},},red:{after:{// after 2 seconds, transition to green2000:{target:'green'},},},},});
Отложенные переходы можно указать так же, как вы указываете их в свойстве on: ... Они могут быть явными:
Или отложенные переходы могут быть обусловлены несколькими задержками. Будет выполнен первый выбранный отложенный переход, который предотвратит выполнение последующих переходов. В следующем примере, если условие trafficIsLight истинно, то более поздний переход 2000: 'yellow' не будет выполняться:
1 2 3 4 5 6 7 8 91011
// ...states:{green:{after:{1000:{target:'yellow',cond:'trafficIsLight'},// always transition to 'yellow' after 2 seconds2000:{target:'yellow'}}}}// ...
Условные отложенные переходы также можно указать в виде массива:
Если вы просто хотите отправить событие после задержки, вы можете указать delay в качестве опции во втором аргументе создателя действия send(...):
12345678
import{actions}from'xstate';const{send}=actions;// action to send the 'TIMER' event after 1 secondconstsendTimerAfter1Second=send({type:'TIMER'},{delay:1000});
Вы также можете предотвратить отправку этих отложенных событий, отменив их. Это делается с помощью создателя действия cancel(...):
import{actions}from'xstate';const{send,cancel}=actions;// action to send the 'TIMER' event after 1 secondconstsendTimerAfter1Second=send({type:'TIMER'},{delay:1000,id:'oneSecondTimer',// give the event a unique ID});// pass the ID of event to cancelconstcancelTimer=cancel('oneSecondTimer');consttoggleMachine=createMachine({id:'toggle',initial:'inactive',states:{inactive:{entry:sendTimerAfter1Second,on:{TIMER:{target:'active'},CANCEL:{actions:cancelTimer},},},active:{},},});// if the CANCEL event is sent before 1 second,// the TIMER event will be canceled.
Параметр delay также может быть вычислен как выражение задержки, которое представляет собой функцию, которая принимает текущий контекст context и событие event, вызвавшее действие send(), и возвращает вычисленный delay (в миллисекундах):
Свойство after: ... не вносит ничего нового в семантику диаграммы состояний. Вместо этого он создает обычные переходы, которые выглядят следующим образом:
Интерпретируемая диаграмма состояний будет отправлять send(...) события after(...) после их задержки delay, если только узел состояния не будет закрыт, что отменит cancel(...) эти отложенные события send(...).