SlideShare a Scribd company logo
1 of 68
Download to read offline
BEYOND THE CALLBACK:
Yield Control with Javascript Generators
JuLy 16, 2015
Darren Cruse darren.cruse@gmail.com
STORY TIME…
(put on your jammies)
Once upon a
time…
When you were young
• And learning to
program at your
momma’s knee…
She said	
• Break your big long
sections of code into little
functions that do just one
thing each
Let the main routine call the little
ones
• And they will each run
• Until they’re done
• And return to the main
function
This is called “Control Flow”
• Can you say “control
flow”?
(I knew you could)
And then one day…
• (maybe in Colorado)
Momma said
• How about we try
something new?
Instead of that function you’ve been
used to…
• The one that starts at
the top
• And executes till it’s
done
• And then just returns
Let’s have us a function
• That’s starts at the
beginning like
normal
• But returns from
the middle
• Not when it’s
done done, but
maybe when it’s
just part way
done
• But if we call it again
• Let’s have it start up
in the middle again
• And then we can have it
do some stuff
• And then maybe return
from the middle again
• So when we call it again
• It can start up in the
middle again
• And then maybe we could
do this three or four times
• And maybe throw some
loops in there
• And then eventually when
the function is really
“done done”
• it can return
• And be finished
• Like we’re used to with
our other functions
So what do you think
About this new kind of function?
Sound good?
But wait a minute
Was your momma maybe kind of
an academic type?
Did she also use
words like…
“lazy sequences”
!
“coroutines”
!
“delimited continuations”
!
“callcc”
If so…
Then yo momma wasn’t on “the
pipe”.
Yo momma was talking about
Generator Functions!!!
(as added by the ecmascript 6 standard)
And yo momma deserves credit
(as does the es6 committee)
For trying to teach
your sorry a** about
alternative means of
control flow…
And thereby save you from
the fate of heavyweight
multithreading that
doesn’t scale, and shared
state concurrency with
rampant race conditions
Which is the true…
Enough silliness
In computer science, a generator is a special routine that can be
used to control the iteration behaviour of a loop. In fact, all
generators are iterators.[1] A generator is very similar to a
function that returns an array, in that a generator has
parameters, can be called, and generates a sequence of values.
However, instead of building an array containing all the values
and returning them all at once, a generator yields the values one
at a time, which requires less memory and allows the caller to
get started processing the first few values immediately. In short,
a generator looks like a function but behaves like an iterator.
From wikipedia:
https://en.wikipedia.org/wiki/Generator_(computer_programming)
2.1 Lisp
2.2 CLU
2.3 Icon
2.4 C++
2.5 Perl
2.6 Tcl
2.7 Haskell
2.8 Racket
2.9 PHP
2.10 Ruby
2.11 Java
2.12 C#
2.13 XL
2.14 F#
Also from wikipedia:
I was surprised to see the number of languages with
generators (not all are “native” though)
The typical generator example is very often…
An infinite Fibonacci Sequence
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
!
var gen = fibonacci();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // 5
console.log(gen.next().value); // 8
again from: https://en.wikipedia.org/wiki/Generator_(computer_programming)
“yield” indicates to
yield the value “curr”
to the caller. This is
also where the function
will resume next time.
Picking it apart…
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] =
[curr, prev + curr];
}
}
again from: https://en.wikipedia.org/wiki/Generator_(computer_programming)
The “*” in “function*” indicates
this is a generator function
Each call to “gen.next()”
runs the generator till
the next yield (or till the
function returns), and
gets back an object
containing the yielded
(or returned) value.
Picking it apart…
var gen = fibonacci();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // 5
console.log(gen.next().value); // 8
again from: https://en.wikipedia.org/wiki/Generator_(computer_programming)
Calling the function does not run the function body.
Rather it’s like calling a constructor.
It returns a generator object that you can then use
to run (and resume) the function body.
{ value: val, done: true }
What gen.next() returns is:
A little object like:
“value” is the value yielded/returned
“done” is true if the generator “returned” (or
exited without a “return”).
as opposed to a yield.
once a generator is “done” it should not be
“next’ed” (if so it simply returns undefined)
But add the --harmony option on the node command!!
node > v0.11.2
Recent versions of Chrome
Recent versions of Firefox
We can run this code as it is in
Also in the browser in:
For other browsers a transpiler is required…
io.js supports it (by default - no option needed)
The most commonly mentioned transpiler for
generators is from Facebook and is called
“Regenerator”
https://www.npmjs.com/package/regenerator
npm install -g regenerator
regenerator --include-runtime fibonacci-basic.js >
fibonacci-basic-es5.js
Regenerator works by converting your code to a
state machine…
function fibonacci() {
var prev, curr;
!
return regeneratorRuntime.wrap(
	 function fibonacci$(context$1$0) {
while (1) switch (context$1$0.prev = context$1$0.next) {
case 0:
prev = 0;
curr = 1;
case 2:
if (!true) {
context$1$0.next = 9;
break;
}
context$1$0.next = 5;
return curr;
case 5:
prev = curr;
curr = prev + curr;
context$1$0.next = 2;
break;
case 9:
case "end":
return context$1$0.stop();
}
}, marked0$0[0], this);
}
babel has support as well (that uses
Regenerator to do the magic)
!
Traceur supports them as well.
Even though there’s fibonacci
examples everywhere…
• What I found interesting was that almost
immediately after generators came on the scene
there was a spate of “task runners”.
• These are utilities that invert the relationship of
consumer and producer like you see in the fibonacci
example
• In order to simplify asynchronous code where it
looks like it’s “blocking”
Lots-o-Task-Runners
• co (TJ/Visionmedia)
• Q.async (Q)
• Promise.coroutine (bluebird)
• galaxy
• monocle
• suspend
• genny
• gen-run
• coro
• (and on…)
“Paving the cow paths?”
(how about a stampede!!)
Probably so many because:
• 1. People wanted them
• 2. They’re pretty easy to implement
once you have generators.
Remember when you first learned to
program how simple it was…
var myNumber = parseInt(Math.random() * 100);
!
while (true) {
var guess = read.question('What is your guess? ');
if (guess > myNumber) {
console.log('Guess lower.');
} else if (guess < myNumber) {
console.log('Guess higher.');
} else {
console.log('YOU WIN!');
break;
}
}
There are cases when blocking code
really is easier to follow
var myNumber = parseInt(Math.random() * 100);
!
rl.setPrompt('What is your guess? ');
rl.prompt();
!
rl.on('line', function(guess) {
if (guess > myNumber) {
console.log('Guess lower.');
} else if (guess < myNumber) {
console.log('Guess higher.');
} else {
console.log('YOU WIN!');
rl.close();
}
rl.prompt();
}).on('close', function() {
console.log('Thanks for playing.');
process.exit(0);
});
Looking at “co” as an example of a “task
runner”…
var myNumber = parseInt(Math.random() * 100);
!
co(function* playgame() {
while(true) {
var guess = yield prompt('What is your guess? ');
if (guess > myNumber) {
console.log('Guess lower.');
} else if (guess < myNumber) {
console.log('Guess higher.');
} else {
console.log('YOU WIN!');
return "Goodbye";
}
}
})
To clarify - when we used fibonacci we
were the consumer of the generator
function* fibonacci() {
let [prev, curr] = [0, 1];
while (true) {
yield curr;
[prev, curr] = [curr, prev + curr];
}
}
!
var gen = fibonacci();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3
console.log(gen.next().value); // 5
console.log(gen.next().value); // 8
“library” code
“our” code
(=“producer”)
(=“consumer”)
Here things are reversed
var myNumber = parseInt(Math.random() * 100);
!
co(function* playgame() {
while(true) {
var guess = yield prompt('What is your guess?');
!
if (guess > myNumber) {
console.log('Guess lower.');
} else if (guess < myNumber) {
console.log('Guess higher.');
} else {
console.log('YOU WIN!');
return "Goodbye";
}
}
})
We’ve written the “producing” (yielding) code, and hidden
inside the “co” routine is the gen.next() “consuming” code.
In this case “prompt”
would typically return a
promise which is yielded
back to “co”, then “co”
will “gen.next()” us
once the promise
resolves to a value.
!
This is the “secret sauce”
for appearing to block
yet remaining single
threaded as always.
AN EASY METAPHOR…
We “yield” the control flow and let other stuff
(like the event loop)
run until the asynchronous result is ready
But there’s another “metaphor” coming in es7…
Async/Await
Basically the story (more or less) is…
There was a strawman proposal for async/await
at the same time there was a proposal for generators
!
The generators proposal got approved in time for es6
!
The async/await proposal did not but is part of es7
!
The good news is async/await is pretty much the same
idea as “task runners” but with slightly simpler syntax
!
The syntax is known for being similar to what C# has
had - it doesn’t have e.g. function* is has async/await
!
(though some javascript async/await implementations are
using generators internally btw)
!
Also the async/await standard is designed to
complement the new promise standards i.e. to work
well with apis returning promises.
Same control flow - nicer syntax:
var prompt = require('./node_modules/prompt-promise');
!
var myNumber = parseInt(Math.random() * 100);
!
// note instead of function* below we have "async"
async function playgame() {
try {
var gameover = false;
while(!gameover) {
// and instead of yield we "await"
var guess = await prompt('What is your guess? ');
!
if (guess > myNumber) {
console.log('Guess lower.');
} else if (guess < myNumber) {
console.log('Guess higher.');
} else {
console.log('YOU WIN!');
gameover = true;
}
}
console.log('Thanks for playing.');
}
catch(err) {
console.log(err);
}
}
Yay Working Exceptions!!
• Yes those were standard try/catch blocks in that last example!!
• Yay (standard) exceptions work even with asynchronous code!!
• (no special .catch etc. as with promises)
• They work both with the generator “task runners” and with
async/await.
• I didn’t mention but in addition to gen.next() there’s also a
“gen.throw()” which throws an exception at the point the
generator has paused on a “yield”. This is the secret sauce.
SUPER BRIEFLY: 	

SOME INTERESTING USES
OF GENERATORS
Briefly: KOA (http://koajs.com)
• Another TJ/VisionMedia Project (as is “co”)
• Intended as the next generation of “Express” (which TJ/VisionMedia also
developed)
• It’s been able to simplify the writing of middleware greatly since you simply
“yield” to the downstream middleware:
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
console.log('%s %s - %s',
this.method, this.url, ms);
});
get the time before
yield to
downstream
get the time after
Briefly: js-csp
• A “communicating sequential processes” library in javascript - it uses generators in it’s
implementation.
• Modeled off of core.async and google go.
• A key concept is that concurrent processes communicate through channels
• And the default behavior of channels is to block (they can buffer if you want but the
default is to block).
• Think of the simplicity like you see in our “guess this number” example, but waiting
on concurrent processes as opposed to user input.
• See also:
• https://github.com/ubolonton/js-csp
• http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript
• http://swannodette.github.io/2013/08/24/es6-generators-and-csp/
Briefly: js-csp
var {chan,timeout} = csp =
require(‘js-csp');
!
var ch = chan();
!
go {
var val;
while((val = <- ch) !== csp.CLOSED) {
console.log(val);
}
}
!
go {
ch <- 1;
(<- timeout(1000));
ch <- 2;
ch.close();
}
This example uses js-csp with sweet.js macros I based on some
started by James Long. Note <- is a blocking channel operation
(i.e. it’s doing a yield behind it)
a channel to
talk over
run this
reader guy
concurrently
with
this writer guy
wait for the writer
wait for the reader
js-csp in the browser (w/out sweet macros this time)
(thanks David Nolen & James Long)
• How about being able to block on a channel of events?
Really changes how you think about UI programming!!
function listen(el, type) {
var ch = chan();
el.addEventListener(type, function(e) {
csp.putAsync(ch, e);
});
return ch;
}
!
go(function*() {
var el = document.querySelector('#ui1');
var ch = listen(el, 'mousemove');
while(true) {
var e = yield take(ch);
el.innerHTML = ((e.layerX||e.clientX)+', ' +
(e.layerY || e.clientY));
}
});
create channel of
“type” events on “el”
concurrent with
other stuff happening
on the page
wait for mouse
moves and display
them
http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript
THANKS FOR COMING

More Related Content

What's hot

Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)
 Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version) Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)
Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)Tobias Pfeiffer
 
How fast is it really? Benchmarking in Practice (Ruby Version)
How fast is it really? Benchmarking in Practice (Ruby Version)How fast is it really? Benchmarking in Practice (Ruby Version)
How fast is it really? Benchmarking in Practice (Ruby Version)Tobias Pfeiffer
 
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and GesturesCreating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and GesturesJussi Pohjolainen
 
Rapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsRapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsGiorgio Pomettini
 
Raspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsRaspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsStephen Chin
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simplerAlexander Mostovenko
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
DAHO.AM 2015 - Abusing phones to make the internet of things
DAHO.AM 2015 - Abusing phones to make the internet of thingsDAHO.AM 2015 - Abusing phones to make the internet of things
DAHO.AM 2015 - Abusing phones to make the internet of thingsJan Jongboom
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsShinpei Hayashi
 
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensZabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensNETWAYS
 
[HITB Malaysia 2011] Exploit Automation
[HITB Malaysia 2011] Exploit Automation[HITB Malaysia 2011] Exploit Automation
[HITB Malaysia 2011] Exploit AutomationMoabi.com
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012Martin Schuhfuß
 
Non stop random2b
Non stop random2bNon stop random2b
Non stop random2bphanhung20
 
[Kiwicon 2011] Post Memory Corruption Memory Analysis
[Kiwicon 2011] Post Memory Corruption Memory Analysis[Kiwicon 2011] Post Memory Corruption Memory Analysis
[Kiwicon 2011] Post Memory Corruption Memory AnalysisMoabi.com
 
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!Paulien van Alst
 
Servletand sessiontracking
Servletand sessiontrackingServletand sessiontracking
Servletand sessiontrackingvamsi krishna
 
Building a turn-based game prototype using ECS - Unite Copenhagen 2019
Building a turn-based game prototype using ECS - Unite Copenhagen 2019Building a turn-based game prototype using ECS - Unite Copenhagen 2019
Building a turn-based game prototype using ECS - Unite Copenhagen 2019Unity Technologies
 

What's hot (20)

Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)
 Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version) Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)
Stop Guessing and Start Measuring - Benchmarking Practice (Poly Version)
 
How fast is it really? Benchmarking in Practice (Ruby Version)
How fast is it really? Benchmarking in Practice (Ruby Version)How fast is it really? Benchmarking in Practice (Ruby Version)
How fast is it really? Benchmarking in Practice (Ruby Version)
 
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and GesturesCreating Asha Games: Game Pausing, Orientation, Sensors and Gestures
Creating Asha Games: Game Pausing, Orientation, Sensors and Gestures
 
Rapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjectsRapid prototyping with ScriptableObjects
Rapid prototyping with ScriptableObjects
 
Raspberry pi gaming 4 kids
Raspberry pi gaming 4 kidsRaspberry pi gaming 4 kids
Raspberry pi gaming 4 kids
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
DAHO.AM 2015 - Abusing phones to make the internet of things
DAHO.AM 2015 - Abusing phones to make the internet of thingsDAHO.AM 2015 - Abusing phones to make the internet of things
DAHO.AM 2015 - Abusing phones to make the internet of things
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring Effects
 
Tulip
TulipTulip
Tulip
 
Zabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet MensZabbix LLD from a C Module by Jan-Piet Mens
Zabbix LLD from a C Module by Jan-Piet Mens
 
[HITB Malaysia 2011] Exploit Automation
[HITB Malaysia 2011] Exploit Automation[HITB Malaysia 2011] Exploit Automation
[HITB Malaysia 2011] Exploit Automation
 
The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012The event-driven nature of javascript – IPC2012
The event-driven nature of javascript – IPC2012
 
Non stop random2b
Non stop random2bNon stop random2b
Non stop random2b
 
libGDX: Scene2D
libGDX: Scene2DlibGDX: Scene2D
libGDX: Scene2D
 
[Kiwicon 2011] Post Memory Corruption Memory Analysis
[Kiwicon 2011] Post Memory Corruption Memory Analysis[Kiwicon 2011] Post Memory Corruption Memory Analysis
[Kiwicon 2011] Post Memory Corruption Memory Analysis
 
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!
GOTO AMS 2019 Upgrade Time! Choose Java 11 or the other one… Kotlin!
 
Servletand sessiontracking
Servletand sessiontrackingServletand sessiontracking
Servletand sessiontracking
 
Building a turn-based game prototype using ECS - Unite Copenhagen 2019
Building a turn-based game prototype using ECS - Unite Copenhagen 2019Building a turn-based game prototype using ECS - Unite Copenhagen 2019
Building a turn-based game prototype using ECS - Unite Copenhagen 2019
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 

Similar to Beyond the Callback: Yield Control with Javascript Generators

Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)William Farrell
 
Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)Oky Firmansyah
 
Event driven javascript
Event driven javascriptEvent driven javascript
Event driven javascriptFrancesca1980
 
Event driven javascript
Event driven javascriptEvent driven javascript
Event driven javascriptFrancesca1980
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...Doug Jones
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
JavaScript Async for Effortless UX
JavaScript Async for Effortless UXJavaScript Async for Effortless UX
JavaScript Async for Effortless UX재석 강
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterSimen Li
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good TestsTomek Kaczanowski
 
7 Sins of Java fixed in Kotlin
7 Sins of Java fixed in Kotlin7 Sins of Java fixed in Kotlin
7 Sins of Java fixed in KotlinLuca Guadagnini
 
Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.Peter Higgins
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsLeonardo Borges
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptjnewmanux
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring frameworkSunghyouk Bae
 

Similar to Beyond the Callback: Yield Control with Javascript Generators (20)

Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)Building Hermetic Systems (without Docker)
Building Hermetic Systems (without Docker)
 
Cc code cards
Cc code cardsCc code cards
Cc code cards
 
Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)Introduction to modern c++ principles(part 1)
Introduction to modern c++ principles(part 1)
 
Event driven javascript
Event driven javascriptEvent driven javascript
Event driven javascript
 
Event driven javascript
Event driven javascriptEvent driven javascript
Event driven javascript
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
JavaScript: The Good Parts Or: How A C# Developer Learned To Stop Worrying An...
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
JavaScript Async for Effortless UX
JavaScript Async for Effortless UXJavaScript Async for Effortless UX
JavaScript Async for Effortless UX
 
Node.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitterNode.js Event Loop & EventEmitter
Node.js Event Loop & EventEmitter
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
While loop
While loopWhile loop
While loop
 
33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests33rd Degree 2013, Bad Tests, Good Tests
33rd Degree 2013, Bad Tests, Good Tests
 
7 Sins of Java fixed in Kotlin
7 Sins of Java fixed in Kotlin7 Sins of Java fixed in Kotlin
7 Sins of Java fixed in Kotlin
 
Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.Your Library Sucks, and why you should use it.
Your Library Sucks, and why you should use it.
 
Functional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event SystemsFunctional Reactive Programming / Compositional Event Systems
Functional Reactive Programming / Compositional Event Systems
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
02 - Prepcode
02 - Prepcode02 - Prepcode
02 - Prepcode
 
JavaScript for real men
JavaScript for real menJavaScript for real men
JavaScript for real men
 
Kotlin coroutines and spring framework
Kotlin coroutines and spring frameworkKotlin coroutines and spring framework
Kotlin coroutines and spring framework
 

Recently uploaded

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 

Beyond the Callback: Yield Control with Javascript Generators

  • 1. BEYOND THE CALLBACK: Yield Control with Javascript Generators JuLy 16, 2015 Darren Cruse darren.cruse@gmail.com
  • 2. STORY TIME… (put on your jammies)
  • 4. When you were young • And learning to program at your momma’s knee…
  • 5. She said • Break your big long sections of code into little functions that do just one thing each
  • 6. Let the main routine call the little ones • And they will each run • Until they’re done • And return to the main function
  • 7. This is called “Control Flow” • Can you say “control flow”?
  • 8. (I knew you could)
  • 9. And then one day… • (maybe in Colorado)
  • 10. Momma said • How about we try something new?
  • 11. Instead of that function you’ve been used to… • The one that starts at the top • And executes till it’s done • And then just returns
  • 12. Let’s have us a function • That’s starts at the beginning like normal
  • 13. • But returns from the middle • Not when it’s done done, but maybe when it’s just part way done
  • 14. • But if we call it again
  • 15. • Let’s have it start up in the middle again
  • 16. • And then we can have it do some stuff • And then maybe return from the middle again
  • 17. • So when we call it again
  • 18. • It can start up in the middle again
  • 19. • And then maybe we could do this three or four times
  • 20. • And maybe throw some loops in there
  • 21. • And then eventually when the function is really “done done” • it can return • And be finished • Like we’re used to with our other functions
  • 22. So what do you think About this new kind of function?
  • 24.
  • 25. But wait a minute
  • 26. Was your momma maybe kind of an academic type?
  • 27. Did she also use words like… “lazy sequences” ! “coroutines” ! “delimited continuations” ! “callcc”
  • 29. Then yo momma wasn’t on “the pipe”.
  • 30. Yo momma was talking about
  • 32. (as added by the ecmascript 6 standard)
  • 33. And yo momma deserves credit
  • 34. (as does the es6 committee)
  • 35. For trying to teach your sorry a** about alternative means of control flow…
  • 36. And thereby save you from the fate of heavyweight multithreading that doesn’t scale, and shared state concurrency with rampant race conditions
  • 37. Which is the true…
  • 39. In computer science, a generator is a special routine that can be used to control the iteration behaviour of a loop. In fact, all generators are iterators.[1] A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values. However, instead of building an array containing all the values and returning them all at once, a generator yields the values one at a time, which requires less memory and allows the caller to get started processing the first few values immediately. In short, a generator looks like a function but behaves like an iterator. From wikipedia: https://en.wikipedia.org/wiki/Generator_(computer_programming)
  • 40. 2.1 Lisp 2.2 CLU 2.3 Icon 2.4 C++ 2.5 Perl 2.6 Tcl 2.7 Haskell 2.8 Racket 2.9 PHP 2.10 Ruby 2.11 Java 2.12 C# 2.13 XL 2.14 F# Also from wikipedia: I was surprised to see the number of languages with generators (not all are “native” though)
  • 41. The typical generator example is very often… An infinite Fibonacci Sequence function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } ! var gen = fibonacci(); console.log(gen.next().value); // 1 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // 3 console.log(gen.next().value); // 5 console.log(gen.next().value); // 8 again from: https://en.wikipedia.org/wiki/Generator_(computer_programming)
  • 42. “yield” indicates to yield the value “curr” to the caller. This is also where the function will resume next time. Picking it apart… function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } again from: https://en.wikipedia.org/wiki/Generator_(computer_programming) The “*” in “function*” indicates this is a generator function
  • 43. Each call to “gen.next()” runs the generator till the next yield (or till the function returns), and gets back an object containing the yielded (or returned) value. Picking it apart… var gen = fibonacci(); console.log(gen.next().value); // 1 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // 3 console.log(gen.next().value); // 5 console.log(gen.next().value); // 8 again from: https://en.wikipedia.org/wiki/Generator_(computer_programming) Calling the function does not run the function body. Rather it’s like calling a constructor. It returns a generator object that you can then use to run (and resume) the function body.
  • 44. { value: val, done: true } What gen.next() returns is: A little object like: “value” is the value yielded/returned “done” is true if the generator “returned” (or exited without a “return”). as opposed to a yield. once a generator is “done” it should not be “next’ed” (if so it simply returns undefined)
  • 45. But add the --harmony option on the node command!! node > v0.11.2 Recent versions of Chrome Recent versions of Firefox We can run this code as it is in Also in the browser in: For other browsers a transpiler is required… io.js supports it (by default - no option needed)
  • 46. The most commonly mentioned transpiler for generators is from Facebook and is called “Regenerator” https://www.npmjs.com/package/regenerator npm install -g regenerator regenerator --include-runtime fibonacci-basic.js > fibonacci-basic-es5.js
  • 47. Regenerator works by converting your code to a state machine… function fibonacci() { var prev, curr; ! return regeneratorRuntime.wrap( function fibonacci$(context$1$0) { while (1) switch (context$1$0.prev = context$1$0.next) { case 0: prev = 0; curr = 1; case 2: if (!true) { context$1$0.next = 9; break; } context$1$0.next = 5; return curr; case 5: prev = curr; curr = prev + curr; context$1$0.next = 2; break; case 9: case "end": return context$1$0.stop(); } }, marked0$0[0], this); }
  • 48. babel has support as well (that uses Regenerator to do the magic) ! Traceur supports them as well.
  • 49. Even though there’s fibonacci examples everywhere… • What I found interesting was that almost immediately after generators came on the scene there was a spate of “task runners”. • These are utilities that invert the relationship of consumer and producer like you see in the fibonacci example • In order to simplify asynchronous code where it looks like it’s “blocking”
  • 50. Lots-o-Task-Runners • co (TJ/Visionmedia) • Q.async (Q) • Promise.coroutine (bluebird) • galaxy • monocle • suspend • genny • gen-run • coro • (and on…)
  • 51. “Paving the cow paths?” (how about a stampede!!)
  • 52. Probably so many because: • 1. People wanted them • 2. They’re pretty easy to implement once you have generators.
  • 53. Remember when you first learned to program how simple it was… var myNumber = parseInt(Math.random() * 100); ! while (true) { var guess = read.question('What is your guess? '); if (guess > myNumber) { console.log('Guess lower.'); } else if (guess < myNumber) { console.log('Guess higher.'); } else { console.log('YOU WIN!'); break; } }
  • 54. There are cases when blocking code really is easier to follow var myNumber = parseInt(Math.random() * 100); ! rl.setPrompt('What is your guess? '); rl.prompt(); ! rl.on('line', function(guess) { if (guess > myNumber) { console.log('Guess lower.'); } else if (guess < myNumber) { console.log('Guess higher.'); } else { console.log('YOU WIN!'); rl.close(); } rl.prompt(); }).on('close', function() { console.log('Thanks for playing.'); process.exit(0); });
  • 55. Looking at “co” as an example of a “task runner”… var myNumber = parseInt(Math.random() * 100); ! co(function* playgame() { while(true) { var guess = yield prompt('What is your guess? '); if (guess > myNumber) { console.log('Guess lower.'); } else if (guess < myNumber) { console.log('Guess higher.'); } else { console.log('YOU WIN!'); return "Goodbye"; } } })
  • 56. To clarify - when we used fibonacci we were the consumer of the generator function* fibonacci() { let [prev, curr] = [0, 1]; while (true) { yield curr; [prev, curr] = [curr, prev + curr]; } } ! var gen = fibonacci(); console.log(gen.next().value); // 1 console.log(gen.next().value); // 1 console.log(gen.next().value); // 2 console.log(gen.next().value); // 3 console.log(gen.next().value); // 5 console.log(gen.next().value); // 8 “library” code “our” code (=“producer”) (=“consumer”)
  • 57. Here things are reversed var myNumber = parseInt(Math.random() * 100); ! co(function* playgame() { while(true) { var guess = yield prompt('What is your guess?'); ! if (guess > myNumber) { console.log('Guess lower.'); } else if (guess < myNumber) { console.log('Guess higher.'); } else { console.log('YOU WIN!'); return "Goodbye"; } } }) We’ve written the “producing” (yielding) code, and hidden inside the “co” routine is the gen.next() “consuming” code. In this case “prompt” would typically return a promise which is yielded back to “co”, then “co” will “gen.next()” us once the promise resolves to a value. ! This is the “secret sauce” for appearing to block yet remaining single threaded as always.
  • 58. AN EASY METAPHOR… We “yield” the control flow and let other stuff (like the event loop) run until the asynchronous result is ready
  • 59. But there’s another “metaphor” coming in es7… Async/Await
  • 60. Basically the story (more or less) is… There was a strawman proposal for async/await at the same time there was a proposal for generators ! The generators proposal got approved in time for es6 ! The async/await proposal did not but is part of es7 ! The good news is async/await is pretty much the same idea as “task runners” but with slightly simpler syntax ! The syntax is known for being similar to what C# has had - it doesn’t have e.g. function* is has async/await ! (though some javascript async/await implementations are using generators internally btw) ! Also the async/await standard is designed to complement the new promise standards i.e. to work well with apis returning promises.
  • 61. Same control flow - nicer syntax: var prompt = require('./node_modules/prompt-promise'); ! var myNumber = parseInt(Math.random() * 100); ! // note instead of function* below we have "async" async function playgame() { try { var gameover = false; while(!gameover) { // and instead of yield we "await" var guess = await prompt('What is your guess? '); ! if (guess > myNumber) { console.log('Guess lower.'); } else if (guess < myNumber) { console.log('Guess higher.'); } else { console.log('YOU WIN!'); gameover = true; } } console.log('Thanks for playing.'); } catch(err) { console.log(err); } }
  • 62. Yay Working Exceptions!! • Yes those were standard try/catch blocks in that last example!! • Yay (standard) exceptions work even with asynchronous code!! • (no special .catch etc. as with promises) • They work both with the generator “task runners” and with async/await. • I didn’t mention but in addition to gen.next() there’s also a “gen.throw()” which throws an exception at the point the generator has paused on a “yield”. This is the secret sauce.
  • 63. SUPER BRIEFLY: SOME INTERESTING USES OF GENERATORS
  • 64. Briefly: KOA (http://koajs.com) • Another TJ/VisionMedia Project (as is “co”) • Intended as the next generation of “Express” (which TJ/VisionMedia also developed) • It’s been able to simplify the writing of middleware greatly since you simply “yield” to the downstream middleware: app.use(function *(next){ var start = new Date; yield next; var ms = new Date - start; console.log('%s %s - %s', this.method, this.url, ms); }); get the time before yield to downstream get the time after
  • 65. Briefly: js-csp • A “communicating sequential processes” library in javascript - it uses generators in it’s implementation. • Modeled off of core.async and google go. • A key concept is that concurrent processes communicate through channels • And the default behavior of channels is to block (they can buffer if you want but the default is to block). • Think of the simplicity like you see in our “guess this number” example, but waiting on concurrent processes as opposed to user input. • See also: • https://github.com/ubolonton/js-csp • http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript • http://swannodette.github.io/2013/08/24/es6-generators-and-csp/
  • 66. Briefly: js-csp var {chan,timeout} = csp = require(‘js-csp'); ! var ch = chan(); ! go { var val; while((val = <- ch) !== csp.CLOSED) { console.log(val); } } ! go { ch <- 1; (<- timeout(1000)); ch <- 2; ch.close(); } This example uses js-csp with sweet.js macros I based on some started by James Long. Note <- is a blocking channel operation (i.e. it’s doing a yield behind it) a channel to talk over run this reader guy concurrently with this writer guy wait for the writer wait for the reader
  • 67. js-csp in the browser (w/out sweet macros this time) (thanks David Nolen & James Long) • How about being able to block on a channel of events? Really changes how you think about UI programming!! function listen(el, type) { var ch = chan(); el.addEventListener(type, function(e) { csp.putAsync(ch, e); }); return ch; } ! go(function*() { var el = document.querySelector('#ui1'); var ch = listen(el, 'mousemove'); while(true) { var e = yield take(ch); el.innerHTML = ((e.layerX||e.clientX)+', ' + (e.layerY || e.clientY)); } }); create channel of “type” events on “el” concurrent with other stuff happening on the page wait for mouse moves and display them http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript