Spawn(生成)
有时调用演员可能不够灵活。例如,您可能希望:
- 调用跨越_多个_状态的子机器
- 调用_动态数量_的演员
您可以通过生成演员而不是调用来实现这一点。通过生成创建的演员是生成演员,而通过调用创建的演员是调用演员。
有两种生成方式:spawnChild动作创建器,或assign的spawn辅助函数。
在大多数情况下,优先使用spawnChild,它会导致生成一个演员,并且可以接受一个可配置的ID以便稍后引用该演员:
createMachine({
entry: spawnChild(childMachine, {
id: 'child'
})
})
您可以使用 spawnChild 生成多个演员:
createMachine({
entry: [
spawnChild(childMachine, { id: 'child-1' }),
spawnChild(childMachine, { id: 'child-2' }),
spawnChild(childMachine, { id: 'child-3' })
]
})
您还可以使用 assign 动作创建器提供的 spawn 辅助函数,它允许您将生成的演员的引用(ActorRef)存储在机器的 context 中:
const parentMachine = createMachine({
entry: [
assign({
childMachineRef: ({ spawn }) => spawn(childMachine, { id: 'child' })
})
]
});
但是,如果您使用 spawn,请确保在不再需要生成的演员时将 ActorRef 从 context 中移除以防止内存泄漏:
actions: [
stopChild('child'),
assign({ childMachineRef: undefined })
]
您可以根据需要 spawn 任意数量的演员:
const childMachine = createMachine({
/* ... */
});
const parentMachine = createMachine({
entry: [
assign({
childMachineRefs: ({ spawn }) => [
spawn(childMachine),
spawn(childMachine),
spawn(childMachine),
],
}),
],
});
如果您不需要跟踪生成演员的引用(例如:对于匿名生成的演员),您可以使用 spawnChild 动作创建器。它不会返回引用,但会向 XState 解释器指示应生成一个新演员:
createMachine({
entry: spawnChild('workflow', {
id: 'workflow'
})
})
API
actions: assign({
ref: ({ spawn }) => spawn(fromPromise(...), {
id: 'some-id',
})
})
spawn(actorBehavior, options?)actorBehavior- 要生成的演员的行为。这可以是函数、promise、observable 或回调。options- 生成演员的选项。id(可选) - 演员的 ID。这用于在状态机中引用演员。input(可选) - 传递给演员的输入。systemId(可选) - 标识演员的字符串,系统范围内唯一。
来源
- 内联:
spawn(fromPromise(...)) - 引用:
spawn('getUser').provide({ actors })
生命周期
- 在生成时创建并启动
- 在机器停止时停止
- 可以手动停止
停止演员
您可以通过“停止子演员”动作停止子演员。此动作由 stopChild(id) 动作创建器创建。
import { setup, stopChild, fromPromise } from 'xstate';
const machine = setup({
actors: {
something: fromPromise(async () => {
// 一些演员逻辑
return 'Some response';
})
}
}).createMachine({
context: ({ spawn }) => ({
something: spawn('something', { id: 'thing' })
}),
// ...
on: {
'thing.stop': {
actions: stopChild('thing')
},
'thing.stopFromContext': {
actions: stopChild(({ context }) => context.something)
}
}
});
停止子演员并不会将其从 context 中移除。要将其从 context 中移除,请使用 assign(...) 动作创建器:
import { setup, stopChild } from 'xstate';
const machine = setup({
// ...
}).createMachine({
context: ({ spawn }) => ({
something: spawn('something', { id: 'thing' })
}),
// ...
on: {
'thing.stop': {
actions: [
stopChild('thing'),
assign({ something: undefined })
]
}
}
});
生成和 TypeScript
即将推出
生成速查表
即将推出