Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Asynchronous Programming with Promises

Asynchronous Programming with Promises

This presentation focuses on improving asynchronous programming in Node.js by using promises with a focus on Q.

Justin DeWind

March 27, 2012
Tweet

More Decks by Justin DeWind

Other Decks in Programming

Transcript

  1. I work for My name is Justin DeWind Twitter @dewind

    GitHub https://github.com/dewind Tuesday, March 27, 12
  2. Node.js and I/O • Network, Database, or file system operations

    are generally non-blocking • There are a lot non-blocking APIs in Node.js • Most of them are callback driven Tuesday, March 27, 12
  3. The “Pyramid of Doom” • Nested callback structures are unwieldy

    and unreadable • They cloud the intent and readability of your code • Node.js APIs are generally asynchronous making it a frequent victim Tuesday, March 27, 12
  4. Callback APIs make me sad I.willBuyMilk (err, milk) -> if

    err console.log "I was unable to buy milk. I thought milk was ubiquitous?" else I.willBuyIceCream (err, iceCream) -> if err console.log "Sadly, I was unable to buy ice cream" else I.willBuyChocolateSyrup (err, syrup) -> if err console.log "Argh! So close, yet I will still not have a milkshake" else console.log "I drink it up!" Tuesday, March 27, 12
  5. Programming with Promises • An alternative to callback-based APIs. Improves

    the readability and intent of asynchronous code. • Promise-based APIs will return a promise for an object in the future Tuesday, March 27, 12
  6. The Library • Q (http://github.com/kriskowal/q/) • is a monad •

    Well conceived and fairly flexible • Support for node style callbacks • Relatively easy to integrate it into callback- based APIs Tuesday, March 27, 12
  7. An example I.promiseToBuyMilk() .then( (milk) -> I.promiseToBuyIceCream(), (err) -> console.log

    "I was unable to buy milk. I thought milk was ubiquitous?") .then( (iceCream) -> I.promiseToBuyChocolateSyrup() (err) -> console.log "Sadly, I was unable to buy ice cream") .then( (syrup) -> console.log "I drink it up!" (err) -> console.log "Argh! So close, yet I will still not have a milkshake") Tuesday, March 27, 12
  8. Q and Node Style Callbacks • A node style callback

    is a function where the first argument is an error and the next is a result. • ncall takes a function, an object to execute that function on, and any arguments the function may take Tuesday, March 27, 12
  9. Example Q.ncall(fs.readFile, fs, "./data/seeds.json", "utf-8") # or Q.node(fs.readFile, fs)("./data/seeds.json", "utf-8')

    .then (data) -> json = JSON.parse(data) # Do some interesting stuff .then -> console.log "Done!" .fail -> console.log "Argh!" Tuesday, March 27, 12
  10. Non-Compliance! • Apparently, developers think they can just buck convention

    • That’s OK. Q.defer returns a promise that we can resolve or reject Tuesday, March 27, 12
  11. Contrived Example someLibrary = doThis: (func) -> # Async I/O

    stuff func(result) # Where result is null if it didn't work Tuesday, March 27, 12
  12. someLibrary.qDoThis = -> defer = Q.defer() @doThis (result) -> if

    result defer.resolve result else defer.reject new Error("Didn't get result") defer.promise Tuesday, March 27, 12
  13. Other Libraries • Event Emitter • Not particularly elegant when

    performing a series of operations • Node-fibers (https://github.com/laverdet/ node-fibers) • Provides a blocking style way of executing asynchronous code • Utilizes continuations to defer stack execution until asynchronous operation has completed • Async (https://github.com/caolan/async) Tuesday, March 27, 12