Skip to content

延迟(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, // 或表达式
},
});