The baker is the CPU and they would have to execute one subprocess at a time: baking the cake and preparing the icing. After that, the same person would also have to cover the cake with the icing.
If it was multithreaded we could have only one CPU executing different subprocesses at the same time (baker with more arms).
Or we could have more CPUs (bakers) working in different subprocesses: cake preparation, icing preparation and cake covering.
But in that case, the third subprocess (covering the cake) would need resources from the other two. So it would be necessary to add synchronisation to those actions, but let’s not focus on that right now.
Although multithreading maximises the CPU time, it’s a little bit more complex because it's harder to handle the concurrency, and the results are unpredictable.
If that was the case, my baker would have to keep waiting for the oven to finish baking the cake, for instance, before being able to start the icing preparation.
But let’s say our baker finishes the icing and the cake isn’t baked yet. Without the cake, they would not be able to move to the next step, which is covering the cake with the icing.
That's why we need to make sure that those dependent actions won’t be executed until we have access to the responses they need. For that, we can use promises and I'll talk about that on my next article.