Using ES6 generators in for loops

Generator functions are a new feature in ES6. A generator is a function that can be entered multiple times and each time it will return something else. Generators are definitely strange at first. If you are familiar with the yield keyword in C# and how it is used then you’ll catch up with generators in ES6 quicker than others. I’m not aware of a similar feature in Java. Generators are strongly linked to iterators and arrays as we’ll see in a bit. I believe that Python uses yield as well.

The best thing is if we jump right into it.

The keyword to learn for generators is “yield” like in C#. A generator function must also be decorated with a star *. Here’s an example of a generator function:

function* programmingLanguages() {
  yield 'C#'
  yield 'Java'
  yield 'JavaScript'
  yield 'F#'
}

Looks funny, right? Let’s try to execute the function:

programmingLanguages()

Nothing happens.

It turns out that we have to push a little harder and apply the next() function to get our lazy generator moving:

let langGenerator = programmingLanguages()
let next = langGenerator.next()

Here comes the next interesting bit. langGenerator.next() will return – or yield – an object with two properties: value and done. Here’s what “next” looks like after the next() function was applied for the first time:

{"value":"C#","done":false}

Hmm, ok, let’s call next again:

{"value":"Java","done":false}

…and again…:

{"value":"JavaScript","done":false}

…almost there…:

{"value":"JavaScript","done":false}

…until we finally get the following:

{"done":true}

We still don’t know what on Earth that was but it was fun, wasn’t it? So we have a generator function called programmingLanguages() with a bunch of yield statements. Upon calling the function with next() we enter the function but exit it after yielding the first value “C#”. Then we call next() again, re-enter the function and continue where code execution was left off. We return “Java” this time. This entering-exiting cycle continues until we hit the last yield function and next() returns “done”.

We can use these properties to build a while-loop to iterate through the generator:

function iterateThroughLanguages() {
	let langGenerator = programmingLanguages()
	let next = langGenerator.next()
	while (!next.done) {
		console.log(next.value)
		next = langGenerator.next()
	}
}

You’ll see that the boolean check for the while loop is based on the “done” property of the object returned by the generator.

However, there’s a much better way of iterating through generators using for-of loops:

for (let lang of programmingLanguages()) {
		console.log(lang)
}

A for-of loop is a perfect match for iterating through generators in ES6.

View all posts related to JavaScript here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: