Thanks to visit codestin.com
Credit goes to www.slideshare.net

Event Driven
Javascript
federico.galassi@cleancode.it
slidehare.net/fgalassi
• Event driven programming
• Event driven javascript
• History of javascript design
Software
components
exchange
information
Producers
give
information
Consumers
take
information
Taxonomy of
interaction models
Who is the
producer ?
Known
Where’s Kenny?
Over There!
Unknown
Where’s Kenny?
Where’s Kenny?
Over There!
Who is the
producer ?
known unknown
How does
information flow ?
Pull
Where’s Kenny?
Over There!
Push
Let me know
where’s Kenny
Ok
... later ...
Hey! Over There!
How does
information flow ?
known unknown
pull
push
4 Models of
interaction
known unknown
pull
push
Request
Response
1.
Request
Response
//  method  invocation
weapon  =  armory.buy(“shuriken”)
kenny  =  cartman.findKenny()
kenny.kill(weapon)
SIMPLE
Request
Response
SIMPLE
SEQUENTIAL
Request
Response
SIMPLE
SEQUENTIAL
IMPERATIVE
Request
Response
HUMAN
Request
Response
SEQUENTIAL
IMPERATIVE
Request
Response
TIGHT
COUPLING
SEQUENTIAL
IMPERATIVE
Request
Response
TIGHT
COUPLING
INEFFICIENT
known unknown
pull
push
Request
Response
2.
Anonymous
Request
Response
Anonymous
Request Response
The system decouples
information and its owner
Anonymous
Request Response
load balancer
Anonymous
Request Response
FAILOVERalancer
Anonymous
Request Response
alancer FAILOVER
EXTENSIBLE
Anonymous
Request Response
SYSTEM
COMPLEXITY
known unknown
pull
push
Request
Response
3.
Anonymous
Request
Response
Callback
Callback
//  observer  pattern
cartman.findKenny(
    function(kenny)  {
        kenny.kill(weapon)
})
Don’t call us
We’ll call you
From Sequential
INPUT
STATE
COMPUTATION
OUTPUT
To State Machine
INPUT STATE A
OUTPUT
INPUT STATE B
INPUT STATE C
COMPUTATION
COMPUTATION
Callback
Relinquish control
Just in time is optimal
Callback
Consumer
Producers
Callback
efficiency
Callback
efficiencyEXPLICIT
CONTROL
FLOW
known unknown
pull
push
Request
Response
4.
Anonymous
Request
Response
Callback Event Driven
Callback +
Anonymous
Request Response
=
EVENTS
Home Automation
Example
EVENTS
FAILOVER +
EXTENSIBLE +
efficiency =
-------------------------------------
power
system
COMPLEXITY +
explicit
control flow =
-------------------------------------
chaos
REQUEST RESPONSE
CALLBACK
ANON.
REQUEST
RESPONSE
EVENTS
Expressive Power
Complexity
Javascript
is
event* driven
*technically callback driven
Not
Javascript
Fault
Not
Your
Fault
Just an
HARDER
problem
• Event driven programming
• Event driven javascript
• History of javascript design
In the old days...
Netscape Headquarters
May 1995
This guy had two
problems...
Brendan Eich
Creator of Javascript
1. The world is
Concurrent
... and so is
browser
Network Requests
User Input
LiveScript first shipped in betas of Netscape Navigator 2.0 in
September 1995
2. Very very very
short time
Be
Pragmatic
He could use
Threads ...
Real preemptive
concurrency
Threads
are
Evil
He could use
Coroutines ...
Emulated
cooperative
concurrency
needs a
complex
scheduler
He was a
functional
guy
Not concurrent
Take it easy
Just non-blocking
Callbacks
//  callbacks  give
//  non  linear  execution
wally.takeJob(function  work()  ...)
wally.getCoffee(function  drink()  ...)
//  ...  later  ...
//  first  drink  coffee
//  then  work
Simple event loop
//  make  it  look  concurrent
button.onclick(function()  {
...
})
UI update
Click handler
UI update
Click handler
Click handlerUI
event
queue
time
User click
Non-blocking I/O
//  network  async  api
xhr.onreadystatechange  =  function(){
...
})
//  DOM  manipulations  are  synchronous
//  but  in  memory  so  very  fast
div.innerHTML  =  “Hello”
Javascript won
But
sold its soul
for simplicity
One thread
=
Freeze
No Wait()
function  breakfast()  {
var  bacon  =  bacon()
var  juice  =  orangeJuice()
eat(bacon,  juice)
}
Simple sequential
function  bacon()  {
//  get  bacon
return  bacon
}
computation
function  breakfast()  {
var  bacon  =  bacon()
var  juice  =  orangeJuice()
eat(bacon,  juice)
}
function  bacon()  {
getBacon(function(bacon)  {
//  got  bacon
})
}
Async gets in
wrong
return what?
Break computation
function  breakfast()  {
      var  callback  =  function(bacon)  {
var  juice  =  getOrangeJuice()
eat(bacon,  juice)
}
bacon(callback)
}
function  bacon(callback)  {
//  get  bacon  async
callback(bacon)
}
rest of computation
computation
Break more
function  breakfast()  {
      var  callback  =  function(bacon)  {
var  callback  =  function(juice)  {
eat(bacon,  juice)
}
getOrangeJuice(callback)
}
bacon(callback)
}
rest of computation 1
computation
rest of computation 2
Continuation
Passing
Style
//  simple  sequential  computation
function  A()  {  return  B()  }
function  B()  {  return  C()  }
function  C()  {  return  value  }
A()
it’s Viral1
it’s Viral
//  C  becomes  async,  everything  becomes  async
function  A(callback)  {
B(function(value)  {  callback(value)  })
}
function  B(callback)  {
C(function(value)  {  callback(value)  })
}
function  C(callback)  {  callback(value)  }
A()
2
//  simple  sequential  sleep
sleep(3000)
doSomething()
sleepit’s Hard
//  not  so  simple  sleep
setTimeout(function()  {
doSomething()
},  3000)
sleepit’s Hard
//  simple  sequential  loop
images.forEach(function(url)
var  image  =  fetchImage(url)
image.show()
}
loopit’s Hard
//  fetchImage  is  async
images.forEach(function(url)
fetchImage(url,  function(image)  {
image.show()
})
}
loopit’s Hard
//  Show  them  in  the  right  order
function  processImage()  {
var  url  =  images.shift()
if  (url)  {
fetchImage(url,  function(image)  {
image.show()
processImage()
})
}
}
processImage()
loopit’s Hard
Javascript
sacrificed
convenience
for simplicity
... and it was the
right choice
• Event driven programming
• Event driven javascript
• History of javascript design
How can we
tame
complexity?
Add
Wait()
stupid!
Easy
//  simple  sequential  sleep  with  wait/resume
sleep(3000)
doSomething()
function  sleep(msec)  {
wait(
setTimeout(function()  {
resume()
},  msec)
)
}
sleep
Beautiful
Already done !
http://stratifiedjs.org/
//  write  sequential  logic
function  doOpsABC()  {
waitfor  {
var  x  =  doOpA()
}
and  {
var  y  =  doOpB()
}
return  doOpC(x,y)
}
Transform to
continuation
passing
style
http://nodejs.org/
//  synchronous  read
fs.read(path).wait()
Implement
coroutines
Back to
complexity
Jeremy Ashkenas - CoffeeScript
“I don't think we want to take CoffeeScript down that
path. Open the Pandora's box of injecting special
functions into the runtime, and ... suddenly you have to
worry about being orders of magnitude slower than
normal JS.”
“Case in point, Stratified JS:A virtuoso performance of
JavaScript compilation, but look at what it compiles into.”
https://github.com/jashkenas/coffee-script/issuesearch?state=closed&q=asynchronous#issue/350/comment/330116
Jeremy Ashkenas - CoffeeScript
var getDocument = function(){
waitfor(document) {
resume(db.get(id));
}
return document;
};
var getDocument;
__oni_rt.exec(__oni_rt.Seq(0,__oni_rt.Seq(0,__oni_rt.Nblock(
function(arguments){
getDocument=function (){
return __oni_rt.exec(__oni_rt.Seq(1,__oni_rt.Suspend(
function(arguments, resume){
return __oni_rt.exec(__oni_rt.Seq(0,__oni_rt.Fcall(0,__oni_rt.Nbl
function(arguments){
return resume;
}),__oni_rt.Nblock(function(arguments){
return db.get(id)
})
)),arguments,this)},
function() {
document=arguments[0];
}),__oni_rt.Fcall(0,__oni_rt.Return,__oni_rt.Nblock(
function(arguments){
return document;
})
)),arguments, this)};
}))), this.arguments, this);
“I will be removing wait() in the next release of Node.
It has already been removed from the documentation.”
“A proper implementation of wait() necessitates true
coroutines”
“This sort of mental complication is exactly what I'm
trying to avoid in Node.”
Ryan Dahl - node.js
http://groups.google.com/group/nodejs/msg/df199d233ff17efa
No wait()
Take it easy
Just control flow
Sequence
//  async  sequential  computation
sequence(get,  filter,  process)
function  get(resume)  {
$.get(url,  function(data)  {
resume(data)
})
}
function  filter(resume,  data)  {  ...  }
function  process(resume,  data)  {  ...  }
1
Sequence
//  async  sequential  computation
function  sequence()  {
var  steps  =  arguments.slice()
var  doStep  =  function(val)  {
var  next  =  steps.shift()
if  (next)  {
next.apply(null,  [doStep,  val])
}
}
doStep()
}
2
Functional
programming
first(fetchA,  fetchB,  fetchC,  callback)
every(checkA,  checkB,  checkC,  callback)
map(array,  mapper,  callback)
filter(array,  filter,  callback)
The road is
taking your
control flow
From imperative
//  complex  triple  click  event
var  clicks  =  0,  timeout  =  null
$(“button”).click(function()  {
clicks++
if  (clicks  ==  1)  {
timeout  =  setTimeout(function()  {
clicks  =  0
},  1000)
}
if  (clicks  ==  3)  {
clearTimeout(timeout)
clicks  =  0
$(this).trigger(“tripleclick”)
}
})
To declarative
$(button)
.on(“click”)
.times(3)
.within(“1  second”)
.trigger(“tripleclick”)
Questions?
federico.galassi@cleancode.it

Event Driven Javascript