Параллельные узлы состояний¶
В диаграммах состояний вы можете объявить состояние как параллельное состояние (parallel state). Это означает, что все его дочерние состояния будут выполняться одновременно.
API¶
Узел параллельного состояния указывается на автомате или в любом вложенном составном состоянии путем установки типа type: 'parallel'
.
Например, автомат из примера ниже позволяет одновременно активировать составные состояния upload
и download
. Представьте, что это приложение, в котором вы можете скачивать и загружать файлы одновременно:
const fileMachine = createMachine({
id: 'file',
type: 'parallel',
states: {
upload: {
initial: 'idle',
states: {
idle: {
on: {
INIT_UPLOAD: { target: 'pending' },
},
},
pending: {
on: {
UPLOAD_COMPLETE: { target: 'success' },
},
},
success: {},
},
},
download: {
initial: 'idle',
states: {
idle: {
on: {
INIT_DOWNLOAD: { target: 'pending' },
},
},
pending: {
on: {
DOWNLOAD_COMPLETE: { target: 'success' },
},
},
success: {},
},
},
},
});
console.log(fileMachine.initialState.value);
// => {
// upload: 'idle',
// download: 'idle'
// }
Значение состояния узла параллельного состояния представлено как объект. Это значение состояния объекта можно использовать для дальнейшего перехода в разные состояния в узле параллельного состояния:
console.log(
fileMachine.transition(
{
upload: 'pending',
download: 'idle',
},
{ type: 'UPLOAD_COMPLETE' }
).value
);
// => {
// upload: 'success',
// download: 'idle'
// }
Узел составного состояния может содержать узлы параллельного состояния. Конфигурация такая же, как и для узлов вложенного состояния:
const lightMachine = createMachine({
// not a parallel machine
id: 'light',
initial: 'green',
states: {
green: {
on: {
TIMER: { target: 'yellow' },
},
},
yellow: {
on: {
TIMER: { target: 'red' },
},
},
// nested parallel machine
red: {
type: 'parallel',
states: {
walkSign: {
initial: 'solid',
states: {
solid: {
on: {
COUNTDOWN: { target: 'flashing' },
},
},
flashing: {
on: {
STOP_COUNTDOWN: { target: 'solid' },
},
},
},
},
pedestrian: {
initial: 'walk',
states: {
walk: {
on: {
COUNTDOWN: { target: 'wait' },
},
},
wait: {
on: {
STOP_COUNTDOWN: { target: 'stop' },
},
},
stop: {
type: 'final',
},
},
},
},
},
},
});
console.log(
lightMachine.transition('yellow', { type: 'TIMER' }).value
);
// {
// red: {
// walkSign: 'solid',
// pedestrian: 'walk'
// }
// }