w

JavaScript Generator Functions

Jason Wandrag
3 min readDec 24, 2022

--

An under-rated and over-powered feature that can do wonders

In JavaScript, a generator function is a function that can be paused in the middle of its execution and resumed later, allowing it to produce a sequence of values over time, rather than producing all of its values at once like a regular function. This can be useful for a variety of tasks, such as producing a sequence of numbers, iterating over a data structure, or creating an infinite stream of data.

To create a generator function, you use the function* syntax instead of the regular function syntax. Inside the generator function, you can use the yield keyword to pause the function and produce a value. Here's an example of a simple generator function that produces a sequence of numbers:

function* countFrom(n) {
while (true) {
yield n;
n++;
}
}

const counter = countFrom(1);

console.log(counter.next().value); // 1
console.log(counter.next().value); // 2
console.log(counter.next().value); // 3

Each time you call the next method on the generator object returned by the generator function, the function will resume execution from the point where it was paused and produce the next value in the sequence. When the generator function reaches the end of its execution, it will return an object with a done property set to true, indicating that the generator has completed its sequence.

Generator functions are often used in conjunction with iterators and the for-of loop to iterate over a sequence of values. Here's an example of using a generator function to create an iterator that produces the Fibonacci sequence:

function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
[prev, curr] = [curr, prev + curr];
yield curr;
}
}

for (const n of fibonacci()) {
console.log(n);
if (n >= 1000) {
break;
}
}

Another great use of generator functions is to create form wizards. A form wizard is a user interface that allows a user to complete a multi-step form by navigating through a series of pages, or “steps,” one at a time. You can use a generator function to create a form wizard by creating a generator function that produces the steps of the form as a sequence of values and using the next method to navigate between steps.

Here’s an example of how you might create a form wizard using a generator function:

function* formWizard() {
// Step 1: Collect personal information
const personalInfo = yield {
title: "Personal Information",
fields: [
{ label: "Full Name", type: "text" },
{ label: "Email Address", type: "email" },
{ label: "Phone Number", type: "tel" },
],
};

// Step 2: Collect address information
const addressInfo = yield {
title: "Address Information",
fields: [
{ label: "Street Address", type: "text" },
{ label: "City", type: "text" },
{ label: "State", type: "text" },
{ label: "Zip Code", type: "text" },
],
};

// Step 3: Review and submit form
const review = yield {
title: "Review and Submit",
fields: [
{
label: "Review your information",
type: "review",
data: { personalInfo, addressInfo },
},
],
};

// Return the completed form data
return { personalInfo, addressInfo, review };
}

const wizard = formWizard();

let step;
while (!(step = wizard.next()).done) {
// Render the current step of the form wizard
renderStep(step.value);

// Wait for the user to submit the current step
const formData = await getFormData();

// Pass the form data to the generator function
wizard.next(formData);
}

// The form wizard is complete
const formData = step.value;
submitForm(formData);

In this example, the generator function defines three steps in the form wizard: personal information, address information, and review and submit. Each time the next method is called on the generator object, the generator function produces the next step in the form as an object with a title and a list of fields. The form data for each step is passed to the generator function as an argument to the next method, and the final form data is returned by the generator function when it completes.

Contact me here: LinkedIn | Codepen | Email

--

--

Jason Wandrag

With a passion for front end development, I am aiming to make the web a beautiful place by innovating how we consume information and interact with the web.