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

Asynchronous Promises (Fluent 2014)

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers. →

Asynchronous Promises (Fluent 2014)

Kris Kowal's presentation about asynchronous programming with Promises from O'Reilly's Fluent conference in 2014.

Avatar for Montage Studio

Montage Studio

April 07, 2014

Other Decks in Programming

Transcript

  1. var FS = require("fs");! var readJsonSync = function (path) {!

    var text = FS.readSync(path, "utf-8");! return JSON.parse(text);! }; synchronous
  2. var FS = require("q-io/fs");! var readJsonPromise = Q.async(function *(path) {!

    var text = yield FS.read(path);! return JSON.parse(text);! }); asynchronous—promises and generators
  3. var FS = require("fs");! var readJsonWithNodebacks = function (path, nodeback)

    {! FS.readFile(path, "utf-8", function (error, content) {! var result;! if (error) {! return nodeback(error);! }! try {! result = JSON.parse(result);! } catch (error) {! return nodeback(error);! }! nodeback(null, result);! });! } nodeback
  4. WHAT IS A PROMISE A promise is a proxy for

    a value from another time or place. The promise interface allows us to interact with that value consistently, regardless of whether the value comes from the past or the future, whether that value is near by or far away, or even if the value is demonstrably unavailable.
  5. var Q = require("q");! var deferred = Q.defer();! // ...

    deferred.resolve()! deferred.promise! .then(console.log)! .done(); new Promise(function (resolve, reject) {! // ... resolve()
 })! .then(console.log)! .done(); As with Q ES6 Parlance
  6. var outputPromise = inputPromise! .then(function (inputValue) {! return outputValue;! //

    or! throw outputError;! // or! return outputPromise;! }, function (inputError) {! return outputValue;! // or! throw outputError;! // or! return outputPromise;! });
  7. return getUsername()! .then(function (username) {! return getUser(username);! })! // chained

    because we will not need the! // user name in the next event! .then(function (user) {! return getPassword()! // nested because we need both user and! // password next! .then(function (password) {! if (user.passwordHash !== hash(password)) {! throw new Error("Can't authenticate");! }! });! });
  8. function retry(f, ms, times) {! return Q().then(f)! .then(null, function (error)

    {! if (times > 0) {! return Q()! .delay(ms)! .then(function () {! return retry(f, ms * 2, times - 1);! });! }! });! }
  9. THE POINT OF PROMISES • implicit exception propagation • control

    flow correspondence • decoupling space and time • pipelined message passing • a debugging primitive • object capability programming • …
  10. var Connection = require("q-connection");! var WebSocketServer = require("ws").Server;! var wss

    = new WebSocketServer({port: 8888});! wss.on("connection", function(ws) {! var local = {! greet: function (message) {! console.log("Greeting:", message);! }! };! Connection(ws, local);! }); server
  11. client var Connection = require("q-connection");! var socket = new WebSocket("ws://localhost:8888");!

    var remote = Connection(socket);! remote.invoke("greet", "Hello, World!")! .done();
  12. ASK ME ABOUT • Indefinite Promise Queues • Semaphores •

    Asynchronous Iterators • Generators • Promise Streams • Back Pressure • Limiting Parallelism • State Machines • Streaming Parsers • Reactive Bindings
  13. var Q = require("q");! ! var id = 0;! !

    exports.request = function (url, key) {! var deferred = Q.defer();! var script = document.createElement("script");! var callbackName = "resolveJsonp" + id++;! var join = url.indexOf("?") < 0 ? "?" : "&";! script.src = url + join + key + "=" + callbackName;! window[callbackName] = function (result) {! deferred.resolve(result);! delete window[callbackName];! };! document.head.appendChild(script);! return deferred.promise;! };
  14. this.catImagesPromise = Jsonp.request(! "http://www.reddit.com/r/" + selectedSub + ".json?limit=100",! "jsonp"! )!

    .then(function (jsonData) {! var catImages = [];! for (var i = 0; i < jsonData.data.children.length; i++) {! var item = jsonData.data.children[i];! if (! item.data.url.toLowerCase()! .match(/i.imgur.com\/[a-zA-Z0-9]+.(jpg|gif)/)! ) {! catImages.push(item.data.url.replace(".jpg", "m.jpg"));! }! }! return catImages;! })! .delay(1000);