Created
October 4, 2016 21:36
-
-
Save androide-osorio/94123e4c2389fc47e1cb88b7257529ad to your computer and use it in GitHub Desktop.
ES2015 roadtrip to awesomeness: Generators
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ES2015 Generators | |
*/ | |
// think of ES2015 generators as a new kind of function, | |
// which may be paused in the middle, one or many times, | |
// and resumed later, allowing other code to run during these | |
// periods of pause, and be passed different information | |
// each time it is started or paused, and respond accordingly | |
// to create a generator function, | |
// append an * to the "function" keyword | |
function* listPeople() { | |
// use "yield" expression every time | |
// you need to send something "out" when | |
// pausing the generator | |
yield 'Andrew'; | |
yield 'Cesar'; | |
yield 'Linis'; | |
// yield can be used without any expression at the right. | |
// in these cases, it will just put out "undefined" | |
} | |
// generator functions do not get called immediately | |
// like normal functions. Instead, they return a | |
// generator object. | |
const people = listPeople(); | |
// now, you can access the values the generator yields using the .next() method. | |
// This method returns an object with the requested value | |
// and a boolean that indicates if the generator function | |
// is done with all its values (and therefore, it not return anything else) | |
console.log(people.next()); // { value: 'Andrew', done: false } | |
console.log(people.next().value); // -> "Cesar" | |
console.log(people.next().done); // -> false | |
console.log(people.next().value); // -> "Linis" | |
console.log(people.next().value); // -> undefined | |
console.log(people.next().done); // -> true | |
//------------------------------------------------------------------------------- | |
// scope in generator functions | |
// when declaring variables inside a generator, | |
// they retain their values until all the | |
// yield expressions are complete. | |
function* listScientists() { | |
const scientists = [ | |
{ name: 'Isaac Newton', profession: "physicist" }, | |
{ name: 'Galileo Galilei', profession: "astronomist" }, | |
{ name: 'Alan Turing', profession: "computer scientist" }, | |
{ name: 'Gottfried Wilhelm Leibniz', profession: "mathematician" }, | |
{ name: 'Michel Foucault', profession: "philosopher" }, | |
{ name: 'Amedeo Avogadro', profession: "chemist" } | |
]; | |
for(const scientist of scientists) { | |
yield scientist; | |
} | |
} | |
const scientistList = listScientists(); | |
console.log(scientistList.next().value.name); // -> Isaac Newtown | |
// NOTE: the "scientist" constant inside the generator | |
// is not being re-declared here | |
console.log(scientistList.next().value.name); // -> Galileo Galilei | |
// ---------------------------------------------------------- | |
// the next() method can receive a value. This value is passed in | |
// to the generator and returned by the current yield expression | |
function *complicatedMath(x) { | |
var y = 2 * (yield (x + 1)); //(1) | |
var z = yield (y / 3); // (2) | |
yield (x + y + z); //(3) | |
} | |
const algebra = complicatedMath(5); | |
console.log(algebra.next().value); // -> 6 (1) | |
console.log(algebra.next(12).value); // -> 8 (2) | |
console.log(algebra.next(13).value); // -> 42 (3) | |
// ---------------------------------------------------------- | |
// generators return a data type that is iterable | |
// (i.e: implements Symbol.iterator). Therefore, we can | |
// use for..of to loop through a generator | |
for(const scientist of listScientists()) { | |
console.log(scientist.name); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment