I have also created a git repository with sample code. Feel free to fork it and experiment.
So what is a generator function and why to use it?
In short: it is a function which execution can be paused at the yield expression. When the invokend function yields, it returns the control of execution to the UI thread, so it does not block. It can also act as a kind of “dependency-injection” (more on this later). The other advantage is that it allows to write asynchronous code which looks like synchronous. The obvious advantage is that it avoids the callback hell, nested callback etc. The code is much cleaner and easier to read and reason about.
Under the hood
Explaining how state machines work is beyond the scope of this article (and I do not know enough about them yet).