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

Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfmaor17
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingShane Coughlan
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLionel Briand
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorTier1 app
 

Recently uploaded (20)

Zer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdfZer0con 2024 final share short version.pdf
Zer0con 2024 final share short version.pdf
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full RecordingOpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
OpenChain Education Work Group Monthly Meeting - 2024-04-10 - Full Recording
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Large Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and RepairLarge Language Models for Test Case Evolution and Repair
Large Language Models for Test Case Evolution and Repair
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
Effectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryErrorEffectively Troubleshoot 9 Types of OutOfMemoryError
Effectively Troubleshoot 9 Types of OutOfMemoryError
 

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