We have a generator here and an instance of a generator. These two can communicate. You can send messages from the instance of the generator back to the generator function, and you can send messages from the generator itself to the instance of the generator.
Let's say we want to send a message from the generator to our instance of the generator. We can do so with a yield keyword, putting any value that we want to the right of it. This value will now be returned from the hello.next call that we do, which pauses the generator, this yield keyboard, and returns this value.
If we run our function, we will see that it doesn't only return the value, but it actually returns an object which has a value property of first, which is the value we pass through, and another property called done, which is currently set to false.
Done is set to false because we haven't yet finished executing our generator. It is still paused at this yield keyword. To finish executing the generator, we simply call hello.next again. The second log that I've put out, now has a value of undefined, but done is true now because our generator is now at the end of the function and has finished executing.
If we want to pass a value from our instance of the generator back to the generator function, we can pass a value when we resume the generator with hello.next and assign it to any variable. In our case, I'll call it word, and then console.logout whatever we pass in.
I'm going to pass in a string that says max and start our function again to see what happens. This time, both of our hello.next calls return the value of undefined. We also got max logged out because we logged out the word which we passed in when we resumed the generator.