Generator

Diving Deeper With ES6 Generators


https://codeburst.io/what-are-javascript-generators-and-how-to-use-them-c6f2713fd12e

Generators are functions that you can use to control the iterator. They can be suspended and later resumed at any time.

Declaring generators

However, we cannot create a generator using the arrow function.

We can create generators like this:

code version

generator version

But the most significant change is that it does not ring immediately. And this is the most important feature in generators — we can get the next value in only when we really need it, not all the values at once.

Yield

It’s a bit like return, but not. Return simply returns the value after the function call, and it will not allow you to do anything else after the return statement.

with yield, we save the result of the executing line.

Yield returns a value only once, and the next time you call the same function it will move on to the next yield statement.

Also in generators we always get the object as output. It always has two properties value and done. And as you can expect, value – returned value, and done shows us whether the generator has finished its job or not.

Naturally, it will obey the laws of execution. If we have a return, anything after it will never be executed.

Yield delegator

Yield with asterisk can delegate it’s work to another generator. This way you can chain as many generators as you want.

A great example would be in recursive functions. In order to call yourself, you need to yield delegate it

return

Try Catch

You can wrap generators in try catch functions.
Whenever crash/error happens inside of the generator, our outside try/catch will take care of it.

You can also put yield in your generator function. When you have your generator variable, you can call throw on it, and it will throw the error right at where your yield is.

If you throw(..) an error into a generator, but no try..catch catches it, the error will (just like normal) propagate right back out (and if not caught eventually end up as an unhandled rejection).

Generator calling other generators

Receive return value

Distinction between yield and yield*:
– with yield, the result is whatever is returned at the current expression,
– but with the yield* expression, it iterates through generator function’s yields.

The Pause

A characteristic of using next is that the generator runs code up to the point of the yield. You will get the value where yield is. Then, the code pauses there.

In the below example, it shows this.

We first create a generator “foo”.
Then we create another generator “bar”.

1) We call next on the generator variable “it”, and the generator starts executing the code.
It hits the first yield, which gives 1.

The code pauses here.

2) Then our generator variable call the next next function.

The code continues from the first yield and continues executing.
It moves into foo and then hits the 2nd yield, where it gives 2 as value.

the code pauses.

3) We log we’re about to throw error.

4) We get the generator variable “it” and call “throw”.

At this point, we continue from the last yield, which is at line “yield 2” in the foo function. That is where the generator code has paused.

5) We catch the error in foo, and log it.

There is no yield so we DO NOT pause. Hence we continue execution.

6) We log at 6. Then we see a yield. Hence we pause, and return the execution to the generator variable.

7) We continue with execution on the generator variable “it”. We then call the next function again on the generator variable “it”.

It continues execution from where we left off in the generator, which was an empty yield.
It continues execution and we get to a throw “Oops”. The throw propogate to bar’s catch and gets caught.

It logs the bar catch, and bar finishes running.

Algorithm examples

Shellsort’s skip mechanism


output:

Now jumping 2 across the array
3
5
7
9
Now jumping 5 across the array
1
6

Divide and Conquer concept


output:

—1st next—
divideAndConquer – start: 0, end: 3
mid is 1
LEFT recursion: [0, 0]
divideAndConquer – start: 0, end: 0
reached end
√ 8
—2nd next—
continuing…!
mid needs to be printed.
√ 99
—3rd next—
RIGHT recursion: [2, 3]
divideAndConquer – start: 2, end: 3
mid is 0
LEFT recursion: [0, -1]
divideAndConquer – start: 0, end: -1
left recursion NOT AVAILABLE X
mid needs to be printed.
√ 8
—4th next—
RIGHT recursion: [1, 3]
divideAndConquer – start: 1, end: 3
mid is 1
LEFT recursion: [0, 0]
divideAndConquer – start: 0, end: 0
reached end
√ 8