Martin Fowler recommended Trevor Burnham’s Async JavaScript: Build More Responsive Apps with Less Code. I was interested on the topic and picked the book and I was pretty satisfied with the book. Async JS concepts were opened in a clear way at a proper level for me.
Bunch of notes (mostly for myself) follow:
Understanding Javascript Events
- Javascript thread & event model : single thread & Event Queue
- Note that JS was selected for Node.js because JS being a great fit for nonblocking I/O
- Event sources : I/O & timing functions
- Async function : A function that can cause another function (callback) to run later from the event queue
- Note that in some cases a function is async only sometimes
- Misc advices:
- Async recursion considered as an anti-pattern.
- Never define a potentially synchronous function that returns a value that could be useful for the callback.
- Read the source code for the functions you use.
- Avoid nesting many levels of callbacks.
Distributing Events
- PubSub : distributed events (single incident might cause reactions through the whole application)
- jQuery: on, also $.Callbacks
- Node: EventMitter
- Evented Models (Backbone, Ember.js)
- Note that PubSub isn’t inherently async in itself
Promises/Deferreds
In brief : A Promise is an object that represents a task with two possible results (success & failure) and holds callbacks when one or other outcome has occurred
- Pros :
- encapsulation
- possibility to pass a promise around
- possibility to derive new promises from existing ones
- Two major alternatives
- jQuery promises (from 1.5)
- CommonJS Promises/A
- Incompatible vocabulary, idea pretty much the same
- Deferred : superset of Promise with addition : one can trigger a Deferred straight
- Promise combinations etc
- $.when : “logical AND“
- piping
- jQuery callbacks : done, fail, always, progress
- More and more JS libraries will probably start to return promises. Until then, one can easily convert async functions to Promise generator
Node-style promise generation from a callback:
var reading = $.Deferred(); fs.readFile(filename, 'utf8', function(err) { if(err) { reading.reject(err); } else { reading.resolve(Array.prototype.slice.call(arguments, 1); } }
Flow control with Async.js
- Similarly as Underscore.js can help synchronous iterative code, a flow control library (as Async.js) can help async code.
- Collection methods:
- async.filter, async.forEach (parallel)
- async.filterSeries, async.forEachSeries (sequentially)
- also other “main functional iteration methods”
- Task organization:
- async.series (one task at the same time)
- async.parallel (all tasks at the same time)
- async.queue (n tasks at the same time)
- Lightweight alternative Step
Workers
- JavaScript is single-thread by nature
- Web Workers “part of HTML5“, one can run code in multiple threads
- Inter-process communication with events
- through Event Queue
- data copied & “serialized+deserialized”
- Not supported with all major browsers (yet)
- Inter-process communication with events
- Node Workers with cluster
Async script loading
- script tag is blocking
- browser will continue to read the document and download resources but won’t evaluate them until the script has been downloaded and run
- script in the head → nothing shown before script is downloaded and run
- thus scripts often moved to end of body, unless
- script might be called from inlin
- browser-enhancing script like Modernizr
- script affecting how rendered page looks like
- defer
- “start loading the script right away but don’t run it before document is ready and previous defer scripts are run
- async
- “load & run scripts as soon as possible”
- for independent scripts only
- Programmatic loading
- yepnope : very lightweight way
- Require.js & AMD : for applications with complex script dependencies
Misc links:
- Captain Obvious on JavaScript (Basic functional idioms)
- Javascript Garden