0
WritingAsynchronousJavascript 101       Matt Perpickmatthewperpick@gmail.com       2011.10.14
Javascript 101
How does this work?function loadPage () {    $(‘#spinner’).show();     setupPage();     $(‘#spinner’).hide();}
• A browser window has one thread that  renders the DOM, dispatches events and  executes Javascript.• This thread executes...
It doesn’t.function loadPage () {    // The DOM manipulation tasks    // are not executed until this    // task’s stack cl...
Use an asynchronous           task.function loadPage () {    $(‘#spinner’).show();    // Queue a task to execute    // whe...
Javascript needs Async•   Javascript is single threaded (mostly)•   Long running tasks kill user experience•   Long runnin...
Aside: Types of         Javascript Tasks•   Events•   Timed scripts - setTimeout, setInterval•   Callbacks - Ajax, WebSQL,...
So how you do write   asynchronous     Javascript?
Callbacks!asyncStorage.get(key, function (val) {    doSomething(val);});  •   Javascript has no syntactic way of dealing w...
Callback programming       is hard.
Reason #1:Error Handling
How does this work?try {    asyncStorage.get(key, function (val) {        throw new Error(“argh”);    });} catch (error) {...
It doesn’t.•   Tasks don’t share stacks.•   Thus, errors in asynchronous callbacks won’t    bubble up to callers.•   Error...
Different Styles// Have separate “onSuccess” and “onError”// callbacks. Used by WebSQLDatabase, jQuery, etc.var onSuccess ...
In summary ...•   Passing errors around via callbacks is a pain.•   It requires much more discipline, more testing and    ...
Reason #2:Control Flow
Reason #2:Control Flow
Synchronous Flow is             Easy/**  * Show a list of songs for the artist with  * the given name.  */function showSon...
Async flow is Spaghetti/**  * Show a list of songs for the artist with  * the given name and execute the callback when  * c...
Control Flow Code          Helps•   Avoid a filthy rat’s nest of callbacks.•   Keep your tasks disjoint from your control fl...
Control Flow Libraries• async.js - https://github.com/caolan/async • async functional utilites + control flow• do.js - http...
Let’s check out async.js• One of many means of doing control flow.• asynchronous functional utilities • e.g. each, map• asy...
Examplefunction showSongs (artistName, callback) {    var renderTask = function (songs, renderCallback) {          try {  ...
In summary• Callbacks don’t scale.• You need to build scaffolding to manage the  complexity.• Separate your control flow fr...
Reason #3:Debugging
Ease the pain (a little)•   Add module or class names to console log    messages to easily trace the flow.•   Breakpoints e...
Conclusion•   Writing asynchronous Javascript is hard.•   Complexity can spiral out of control.•   Plan for it.•   Beware....
Fin.Questions? Comments?
Further reading•   http://dev.opera.com/articles/view/timing-and-    synchronization-in-javascript/•   http://ejohn.org/bl...
Prochain SlideShare
Chargement dans... 5
×

Writing Asynchronous Javascript 101

38,205

Published on

A brief introduction to writing asynchronous javascript. A presentation from work.

Published in: Technologies, Affaires
3 commentaires
23 mentions J'aime
Statistiques
Remarques
Aucun téléchargement
Vues
Total des vues
38,205
Sur Slideshare
0
À partir des ajouts
0
Nombre d'ajouts
2
Actions
Partages
0
Téléchargements
160
Commentaires
3
J'aime
23
Ajouts 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Transcript of "Writing Asynchronous Javascript 101"

    1. 1. WritingAsynchronousJavascript 101 Matt Perpickmatthewperpick@gmail.com 2011.10.14
    2. 2. Javascript 101
    3. 3. How does this work?function loadPage () { $(‘#spinner’).show(); setupPage(); $(‘#spinner’).hide();}
    4. 4. • A browser window has one thread that renders the DOM, dispatches events and executes Javascript.• This thread executes one code unit at a time.• Other code units are queued until the current code unit is finished executing.
    5. 5. It doesn’t.function loadPage () { // The DOM manipulation tasks // are not executed until this // task’s stack clears. The spinner // isn’t shown until setUp is // completed. $(‘#spinner’).show(); setupPage(); $(‘#spinner’).hide();}
    6. 6. Use an asynchronous task.function loadPage () { $(‘#spinner’).show(); // Queue a task to execute // when this stack clears. setTimeout(function () { setupPage(); $(‘#spinner’).hide(); }, 0);}
    7. 7. Javascript needs Async• Javascript is single threaded (mostly)• Long running tasks kill user experience• Long running tasks will timeout (especially on mobile browsers)• Thus, most I/O APIs are asynchronous • Ajax, WebSQL, IndexedDB, WebWorkers
    8. 8. Aside: Types of Javascript Tasks• Events• Timed scripts - setTimeout, setInterval• Callbacks - Ajax, WebSQL, WebWorkers, etc.• Script Tags• Javascript URLs• Others?
    9. 9. So how you do write asynchronous Javascript?
    10. 10. Callbacks!asyncStorage.get(key, function (val) { doSomething(val);}); • Javascript has no syntactic way of dealing with asynchronous code (unlike Erlang and co.) • We’re stuck with callbacks. • Callback programming can get complex.
    11. 11. Callback programming is hard.
    12. 12. Reason #1:Error Handling
    13. 13. How does this work?try { asyncStorage.get(key, function (val) { throw new Error(“argh”); });} catch (error) { alert(‘error!’);}
    14. 14. It doesn’t.• Tasks don’t share stacks.• Thus, errors in asynchronous callbacks won’t bubble up to callers.• Errors must be manually passed back to callers via callback functions.• There are two styles of doing this.
    15. 15. Different Styles// Have separate “onSuccess” and “onError”// callbacks. Used by WebSQLDatabase, jQuery, etc.var onSuccess = function (value) { doSomething(value); };var onFailure = function (error) { alert(‘aw shucks’); };asyncStorage.get(key, onSuccess, onFailure);// Use a single callback. If errors occur, they are// passed as the first argument to the callback. It// is up to the caller to check if the first argument// is non-null. This is a node.js convention and is// reminiscent of error checking in C.asyncStorage.get(key, function (error, value) { if (error) { alert(‘aw shucks error’); return; // Don’t forget this! } doSomething(value);});
    16. 16. In summary ...• Passing errors around via callbacks is a pain.• It requires much more discipline, more testing and some understanding of how the browser works.• Consistency is important. Choose one error passing style for your application.
    17. 17. Reason #2:Control Flow
    18. 18. Reason #2:Control Flow
    19. 19. Synchronous Flow is Easy/** * Show a list of songs for the artist with * the given name. */function showSongs (artistName) { var artist = artists.getByName(artistName); var albums = albums.getByArtist(artist); var songs = songs.getByAlbum(albums); songView.render(songs);}
    20. 20. Async flow is Spaghetti/** * Show a list of songs for the artist with * the given name and execute the callback when * complete. */function showSongs (artistName, callback) { // And we’re not even handling errors! artists.getByName(name, function (artist) { albums.getByArtist(artist, function (albums) { songs.getByAlbum(albums, function (songs) { songView.render(songs); return callback(); }); }); });}
    21. 21. Control Flow Code Helps• Avoid a filthy rat’s nest of callbacks.• Keep your tasks disjoint from your control flow.• Control flow is readable in one place.
    22. 22. Control Flow Libraries• async.js - https://github.com/caolan/async • async functional utilites + control flow• do.js - https://github.com/creationix/do • control flow via continuables• jquery.deferred.js - http://jquery.com • promises• language extentions options, others
    23. 23. Let’s check out async.js• One of many means of doing control flow.• asynchronous functional utilities • e.g. each, map• async control flow • e.g. series, parallel, waterfall
    24. 24. Examplefunction showSongs (artistName, callback) { var renderTask = function (songs, renderCallback) { try { songView.render(songs); return renderCallback(null); // No errors! } catch (error) { return renderCallback(error); } }; // The control flow is encapsulated in one place // in clear, concise, readable manner. var tasks = [ async.apply(artists.getByName, artistName), async.apply(albums.getByArtist), async.apply(songs.getByAlbum), async.apply(renderTask) ]; async.waterfall(tasks, callback);}
    25. 25. In summary• Callbacks don’t scale.• You need to build scaffolding to manage the complexity.• Separate your control flow from your tasks.
    26. 26. Reason #3:Debugging
    27. 27. Ease the pain (a little)• Add module or class names to console log messages to easily trace the flow.• Breakpoints everywhere!• This still sucks.
    28. 28. Conclusion• Writing asynchronous Javascript is hard.• Complexity can spiral out of control.• Plan for it.• Beware.• Good luck.
    29. 29. Fin.Questions? Comments?
    30. 30. Further reading• http://dev.opera.com/articles/view/timing-and- synchronization-in-javascript/• http://ejohn.org/blog/how-javascript-timers-work/• http://www.whatwg.org/specs/web-apps/current- work/multipage/webappapis.html#event-loops
    1. A particular slide catching your eye?

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

    ×