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
contr...
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  dr...
Simple event loop
//  make  it  look  concurrent
button.onclick(function()  {
...
})
UI update
Click handler
UI update
Cli...
Non-blocking I/O
//  network  async  api
xhr.onreadystatechange  =  function(){
...
})
//  DOM  manipulations  are  synchr...
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
functi...
function  breakfast()  {
var  bacon  =  bacon()
var  juice  =  orangeJuice()
eat(bacon,  juice)
}
function  bacon()  {
get...
Break computation
function  breakfast()  {
      var  callback  =  function(bacon)  {
var  juice  =  getOrangeJuice()
eat(...
Break more
function  breakfast()  {
      var  callback  =  function(bacon)  {
var  callback  =  function(juice)  {
eat(ba...
Continuation
Passing
Style
//  simple  sequential  computation
function  A()  {  return  B()  }
function  B()  {  return  C()  }
function  C()  {  re...
it’s Viral
//  C  becomes  async,  everything  becomes  async
function  A(callback)  {
B(function(value)  {  callback(valu...
//  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,...
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(...
Beautiful
Already done !
http://stratifiedjs.org/
//  write  sequential  logic
function  doOpsABC()  {
waitfor  {
var  x  =  doOpA()
}
and  {
var  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 injec...
Jeremy Ashkenas - CoffeeScript
var getDocument = function(){
waitfor(document) {
resume(db.get(id));
}
return document;
};...
“I will be removing wait() in the next release of Node.
It has already been removed from the documentation.”
“A proper imp...
No wait()
Take it easy
Just control flow
Sequence
//  async  sequential  computation
sequence(get,  filter,  process)
function  get(resume)  {
$.get(url,  function...
Sequence
//  async  sequential  computation
function  sequence()  {
var  steps  =  arguments.slice()
var  doStep  =  funct...
Functional
programming
first(fetchA,  fetchB,  fetchC,  callback)
every(checkA,  checkB,  checkC,  callback)
map(array,  m...
The road is
taking your
control flow
From imperative
//  complex  triple  click  event
var  clicks  =  0,  timeout  =  null
$(“button”).click(function()  {
cli...
To declarative
$(button)
.on(“click”)
.times(3)
.within(“1  second”)
.trigger(“tripleclick”)
Questions?
federico.galassi@cleancode.it
Upcoming SlideShare
Loading in...5
×

Event Driven Javascript

10,079

Published on

Talk i gave at WebTech Conference on November 10th 2010.

Abstract:
Why is web application programming so difficult? Is it javascript fault? Is it our fault? Time to take the red pill and wake up in the real, event driven world. A world where if you can dodge the bullets of skyrocketing complexity, your programs can be made scalable, fault tolerant, extensible and just beautiful.

Also
http://federico.galassi.net/
http://www.webtechcon.it

Follow me on Twitter!
https://twitter.com/federicogalassi

Published in: Technology, Self Improvement
0 Comments
15 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
10,079
On Slideshare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
104
Comments
0
Likes
15
Embeds 0
No embeds

No notes for slide

Event Driven Javascript

  1. 1. Event Driven Javascript federico.galassi@cleancode.it slidehare.net/fgalassi
  2. 2. • Event driven programming • Event driven javascript • History of javascript design
  3. 3. Software components exchange information
  4. 4. Producers give information
  5. 5. Consumers take information
  6. 6. Taxonomy of interaction models
  7. 7. Who is the producer ?
  8. 8. Known Where’s Kenny? Over There!
  9. 9. Unknown Where’s Kenny? Where’s Kenny? Over There!
  10. 10. Who is the producer ? known unknown
  11. 11. How does information flow ?
  12. 12. Pull Where’s Kenny? Over There!
  13. 13. Push Let me know where’s Kenny Ok ... later ... Hey! Over There!
  14. 14. How does information flow ? known unknown pull push
  15. 15. 4 Models of interaction
  16. 16. known unknown pull push Request Response 1.
  17. 17. Request Response //  method  invocation weapon  =  armory.buy(“shuriken”) kenny  =  cartman.findKenny() kenny.kill(weapon)
  18. 18. SIMPLE Request Response
  19. 19. SIMPLE SEQUENTIAL Request Response
  20. 20. SIMPLE SEQUENTIAL IMPERATIVE Request Response
  21. 21. HUMAN Request Response
  22. 22. SEQUENTIAL IMPERATIVE Request Response TIGHT COUPLING
  23. 23. SEQUENTIAL IMPERATIVE Request Response TIGHT COUPLING INEFFICIENT
  24. 24. known unknown pull push Request Response 2. Anonymous Request Response
  25. 25. Anonymous Request Response The system decouples information and its owner
  26. 26. Anonymous Request Response load balancer
  27. 27. Anonymous Request Response FAILOVERalancer
  28. 28. Anonymous Request Response alancer FAILOVER EXTENSIBLE
  29. 29. Anonymous Request Response SYSTEM COMPLEXITY
  30. 30. known unknown pull push Request Response 3. Anonymous Request Response Callback
  31. 31. Callback //  observer  pattern cartman.findKenny(    function(kenny)  {        kenny.kill(weapon) })
  32. 32. Don’t call us We’ll call you
  33. 33. From Sequential INPUT STATE COMPUTATION OUTPUT
  34. 34. To State Machine INPUT STATE A OUTPUT INPUT STATE B INPUT STATE C COMPUTATION COMPUTATION
  35. 35. Callback Relinquish control
  36. 36. Just in time is optimal Callback Consumer Producers
  37. 37. Callback efficiency
  38. 38. Callback efficiencyEXPLICIT CONTROL FLOW
  39. 39. known unknown pull push Request Response 4. Anonymous Request Response Callback Event Driven
  40. 40. Callback + Anonymous Request Response = EVENTS
  41. 41. Home Automation Example
  42. 42. EVENTS FAILOVER + EXTENSIBLE + efficiency = ------------------------------------- power system COMPLEXITY + explicit control flow = ------------------------------------- chaos
  43. 43. REQUEST RESPONSE CALLBACK ANON. REQUEST RESPONSE EVENTS Expressive Power
  44. 44. Complexity
  45. 45. Javascript is event* driven *technically callback driven
  46. 46. Not Javascript Fault
  47. 47. Not Your Fault
  48. 48. Just an HARDER problem
  49. 49. • Event driven programming • Event driven javascript • History of javascript design
  50. 50. In the old days... Netscape Headquarters May 1995
  51. 51. This guy had two problems... Brendan Eich Creator of Javascript
  52. 52. 1. The world is Concurrent
  53. 53. ... and so is browser
  54. 54. Network Requests User Input
  55. 55. LiveScript first shipped in betas of Netscape Navigator 2.0 in September 1995 2. Very very very short time
  56. 56. Be Pragmatic
  57. 57. He could use Threads ... Real preemptive concurrency
  58. 58. Threads are Evil
  59. 59. He could use Coroutines ... Emulated cooperative concurrency
  60. 60. needs a complex scheduler
  61. 61. He was a functional guy
  62. 62. Not concurrent Take it easy Just non-blocking
  63. 63. Callbacks //  callbacks  give //  non  linear  execution wally.takeJob(function  work()  ...) wally.getCoffee(function  drink()  ...) //  ...  later  ... //  first  drink  coffee //  then  work
  64. 64. 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
  65. 65. Non-blocking I/O //  network  async  api xhr.onreadystatechange  =  function(){ ... }) //  DOM  manipulations  are  synchronous //  but  in  memory  so  very  fast div.innerHTML  =  “Hello”
  66. 66. Javascript won
  67. 67. But sold its soul for simplicity
  68. 68. One thread = Freeze
  69. 69. No Wait()
  70. 70. function  breakfast()  { var  bacon  =  bacon() var  juice  =  orangeJuice() eat(bacon,  juice) } Simple sequential function  bacon()  { //  get  bacon return  bacon } computation
  71. 71. function  breakfast()  { var  bacon  =  bacon() var  juice  =  orangeJuice() eat(bacon,  juice) } function  bacon()  { getBacon(function(bacon)  { //  got  bacon }) } Async gets in wrong return what?
  72. 72. 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
  73. 73. 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
  74. 74. Continuation Passing Style
  75. 75. //  simple  sequential  computation function  A()  {  return  B()  } function  B()  {  return  C()  } function  C()  {  return  value  } A() it’s Viral1
  76. 76. 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
  77. 77. //  simple  sequential  sleep sleep(3000) doSomething() sleepit’s Hard
  78. 78. //  not  so  simple  sleep setTimeout(function()  { doSomething() },  3000) sleepit’s Hard
  79. 79. //  simple  sequential  loop images.forEach(function(url) var  image  =  fetchImage(url) image.show() } loopit’s Hard
  80. 80. //  fetchImage  is  async images.forEach(function(url) fetchImage(url,  function(image)  { image.show() }) } loopit’s Hard
  81. 81. //  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
  82. 82. Javascript sacrificed convenience for simplicity
  83. 83. ... and it was the right choice
  84. 84. • Event driven programming • Event driven javascript • History of javascript design
  85. 85. How can we tame complexity?
  86. 86. Add Wait() stupid!
  87. 87. Easy //  simple  sequential  sleep  with  wait/resume sleep(3000) doSomething() function  sleep(msec)  { wait( setTimeout(function()  { resume() },  msec) ) } sleep
  88. 88. Beautiful
  89. 89. Already done !
  90. 90. http://stratifiedjs.org/ //  write  sequential  logic function  doOpsABC()  { waitfor  { var  x  =  doOpA() } and  { var  y  =  doOpB() } return  doOpC(x,y) }
  91. 91. Transform to continuation passing style
  92. 92. http://nodejs.org/ //  synchronous  read fs.read(path).wait()
  93. 93. Implement coroutines
  94. 94. Back to complexity
  95. 95. 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
  96. 96. 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);
  97. 97. “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
  98. 98. No wait() Take it easy Just control flow
  99. 99. 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
  100. 100. 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
  101. 101. Functional programming first(fetchA,  fetchB,  fetchC,  callback) every(checkA,  checkB,  checkC,  callback) map(array,  mapper,  callback) filter(array,  filter,  callback)
  102. 102. The road is taking your control flow
  103. 103. 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”) } })
  104. 104. To declarative $(button) .on(“click”) .times(3) .within(“1  second”) .trigger(“tripleclick”)
  105. 105. Questions?
  106. 106. federico.galassi@cleancode.it
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×