延迟(after)转换
延迟转换 是在设定的时间后触发的转换。延迟转换对于在应用程序逻辑中构建超时和间隔非常有用。如果在计时器结束之前发生了另一个事件,则转换不会完成。
延迟转换在状态节点的 after
属性上定义,可以是一个数字(以毫秒为单位)或一个引用在 delays
设置对象中定义的延迟的字符串。
import { createMachine } from 'xstate';
const pushTheButtonGame = createMachine({
initial: 'waitingForButtonPush',
states: {
waitingForButtonPush: {
after: {
5000: {
target: 'timedOut',
actions: 'logThatYouGotTimedOut',
},
},
on: {
PUSH_BUTTON: {
actions: 'logSuccess',
target: 'success',
},
},
},
success: {},
timedOut: {},
},
});
延迟
内联延迟
您可以通过直接指定延迟时间(以毫秒为单位)来定义内联延迟:
const machine = createMachine({
initial: 'idle',
states: {
idle: {
after: {
1000: { target: 'nextState' },
},
},
nextState: {},
},
});
这将在 1000 毫秒后转换到 nextState
状态。
引用延迟
您还可以通过指定字符串延迟键并单独提供实际延迟时间来定义引用延迟。
例如:
import { setup } from 'xstate';
const machine = setup({
delays: {
timeout: 1000,
},
}).createMachine(
{
initial: 'idle',
states: {
idle: {
after: {
timeout: { target: 'nextState' },
},
},
nextState: {},
},
}
);
动态延迟
延迟也可以动态定义为返回延迟时间(以毫秒为单位)的函数:
import { setup } from 'xstate';
const machine = setup({
types: {
context: {} as {
attempts: number
}
},
delays: {
timeout: ({ context }) => {
return context.attempts * 1000;
},
},
}).createMachine({
initial: 'attempting',
states: {
attempting: {
after: {
timeout: {
actions: assign({ attempts: ({ context }) => context.attempts + 1 }),
target: 'attempting',
},
},
},
// ...
},
});
生命周期
当状态退出时,延迟转换计时器将被取消。
测试
- 模拟时钟
延迟转换和 TypeScript
您可以通过在 setup()
函数中设置延迟来强类型化您的机器的 delays
:
import { setup } from 'xstate';
const machine = setup({
delays: {
shortTimeout: 1000,
longTimeout: 5000,
eventually: 10_000
}
}).createMachine({
after: {
shortTimeout: {/* ... */}
}
});
延迟转换备忘单
使用下面的 XState 延迟转换备忘单快速入门。
createMachine({
after: {
DELAY: {
/* ... */
},
},
}).provide({
delays: {
延迟: 1000, // 或表达式
},
});