Last active
August 29, 2015 14:02
-
-
Save 19h/06a8fecf4428b9b6406c to your computer and use it in GitHub Desktop.
Node.js Professionals Alliance Berlin #1 Meetup: 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
var Foo = function * (c) { | |
var a = [0, 1], | |
b = 0; | |
for (b = 0; b < c; ++b) { | |
a.push(a[0] + a[1]); | |
a.shift(); | |
yield a[a.length - 1]; | |
} | |
return a[0] | |
} | |
// initialize generator | |
var foo = Foo(12); | |
// kick off generator | |
var a = foo.next(); // { value: 1, done: false } | |
// using for .. of | |
for ( var a of foo ) { | |
console.log(a); | |
/* | |
2 | |
3 | |
5 | |
8 | |
13 | |
21 | |
34 | |
55 | |
89 | |
144 | |
233 | |
*/ | |
} | |
/* | |
^^^^^^^^^^^^^^^^ | |
for .. of will directly use "value" of the result, | |
BUT you won't be able to pass a parameter to .next | |
nor will you be able to .throw from the iterator. | |
*/ |
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
// Math example | |
var FooMath = function * (){ | |
var a = 0; | |
for(;;) { | |
a = yield a; | |
++a; | |
} | |
} | |
/* | |
The first .next will yield 0 (a) and when passed a value, | |
the passed value will substitute the expression and resume | |
at that exact location. Let's mutate "a". | |
*/ | |
var fooMath = FooMath(); | |
fooMath.next(); // { value: 0, done: false } | |
fooMath.next(100); // { value: 101, done: false } |
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
// Hypothetical use in an application | |
/* | |
We have a generator that obtains user data; | |
we will inspect the return values and inject | |
the info that is asked for by using .next | |
and will throw errors in the generator-scope | |
by using the .throw method. | |
*/ | |
var db = { | |
"kenansulayman": { | |
name: "Kenan Sulayman", | |
job: "Software Architect" | |
}, | |
"homerdong": { | |
name: "Homer Dong", | |
job: "PHP veteran" | |
} | |
} | |
var fooGetVal = function * (id){ | |
// user id is "id" | |
var user = { | |
id: id | |
} | |
try { | |
user.name = yield { | |
type: "name", | |
id: id | |
}; | |
} catch(e) { | |
if ( e === "No such id" ) { | |
return yield { | |
type: "result", | |
data: null | |
}; | |
} | |
} | |
yield { | |
type: "result", | |
data: user | |
}; | |
} | |
// this will usually be in a loop: | |
var reaper = function (cb, myGetVal, param) { | |
var retval = myGetVal.next(param).value; // { type: "name", id: "kenansulayman" } | |
if ( retval.type === "name" ) { | |
if ( db[retval.id] ) { | |
param = db[retval.id].name; | |
} else { | |
myGetVal.throw("No such id"); | |
return cb(null); | |
} | |
} | |
if ( retval.type === "result" ) { | |
return cb(retval.data); | |
} | |
return reaper(cb, myGetVal, param) | |
}; | |
var myGetVal = fooGetVal("kenansulayman"); | |
reaper(function (user) { | |
console.log(user); // { id: 'kenansulayman', name: 'Kenan Sulayman' } | |
}, myGetVal); | |
var myGetVal2 = fooGetVal("homerdong"); | |
reaper(function (user) { | |
console.log(user); // { id: 'homerdong', name: 'Homer Dong' } | |
}, myGetVal2); | |
var myGetVal3 = fooGetVal("peter"); | |
reaper(function (user) { | |
console.log(user); // "null"; see line 32 - 35 | |
}, myGetVal3); |
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
var foo = function * () { | |
var a = 10; | |
while (a--) yield a; | |
} | |
var foo2 = function * () { | |
var a = 10; | |
yield* foo(); // delegate to foo^ | |
while (a--) yield Math.random(); | |
} | |
for ( var a of foo2() ) { | |
console.log(a) | |
} | |
// Example output | |
/* | |
9 | |
8 | |
7 | |
6 | |
5 | |
4 | |
3 | |
2 | |
1 | |
0 | |
0.31441035214811563 | |
0.932482686592266 | |
0.49652760615572333 | |
0.5199203079100698 | |
0.7944680366199464 | |
0.21947496198117733 | |
0.7085313643328846 | |
0.11945359944365919 | |
0.20332212862558663 | |
0.15203028940595686 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment