Open RainerAtSpirit opened 3 years ago
@RainerAtSpirit Sorry dude, missed this!
How about this - what if you needed to represent the loading states of the two promises differently? I.e. what if you needed to show in your UI which one failed/which succeeded? Or show how long each one had taken?
Promise.all could cover quite a few cases where these requirements weren't needed, but a parallel machine would let you handle it all.
Agree in general though, if I were implementing it myself and I wasn't going to need the UI to show the state of the promises, I'd just use Promise.all
@mattpocock No worries.
Just for the sake of argument. If the use case requires independent handling, then most probably I'd reach out for the actor
model. e.g. master gets config data and based on the that spawns multiple actors that gets additional data. That way each DetailView
component would become independent.
// contrived partial example
...
context: {
...
parentId: '123',
configs: [],
actorRefs: [],
},
states: {
init: {
invoke: {
src: 'getConfigs',
onDone: {
target: 'done',
actions: assign({
configs: (context, event) => {
return event.data
},
}),
},
onError: {
target: 'error',
},
},
},
done: {
entry: assign((context: any, event) => {
const refs = context.configs.map((config: any) => {
return spawn(createListViewMachine(config, context.projectId))
})
return {
actorRefs: refs,
}
}),
},
// usage with react
export default function App() {
const [current, send] = useMachine(myMachine, { devTools: true })
return (
<div className="App">
<h1>ProjectId {current.context.projectId}</h1>
<h2>{current.value}</h2>
{current.context.actorRefs.map((ref: any) => (
<DetailView key={ref.id} service={ref}></DetailView>
))}
</div>
)
}
https://github.com/mattpocock/xstate-stream-demo-app/blob/cb6d8d9ddceeb1e6e33522e0310b69b53974ff18/src/machines/paymentWizard.machine.ts#L106
I was pretty sure that I was running into this before, see https://github.com/davidkpiano/xstate/issues/359. I'd say it's a great educational example of how to use parallel states correctly. However, in the real world, the question would be if we gain any benefits or if an invoke
Promise.all
could be used instead. In this case, I'm leaning to the second as it makes the machine and its visualization easier.