SlideShare une entreprise Scribd logo
1  sur  44
Télécharger pour lire hors ligne
Sane Async Patterns
       Trevor Burnham
     HTML5DevConf 2013
http://dev.hubspot.com/jobs
https://pragprog.com/books/tbcoffee
https://pragprog.com/books/tbajs
https://leanpub.com/npm
In This Talk

• Callback arguments considered harmful
• Three alternative patterns:
  • PubSub
  • Promises
  • AMD
The Callback Argument
     Anti-Pattern
Pyramid of Doom
mainWindow.menu("File", function(err, file) {
  if(err) throw err;
  file.openMenu(function(err, menu) {
    if(err) throw err;
    menu.item("Open", function(err, item) {
      if(err) throw err;
      item.click(function(err) {
        if(err) throw err;
        window.createDialog('DOOM!', function(err, dialog) {
          if(err) throw err;
          ...
        });
      });
    });
  });
});
A JS-er’s Lament

// Synchronous version of previous slide
try {
  var file = mainWindow.menu("File");
  var menu = file.openMenu();
  var item = menu.item("Open");
  item.click()
  window.createDialog('DOOM!');
} catch (err) {
  ...
}
A Silver Lining

myFunction1();
// No state changes here!
myFunction2();




// Which means we never have to do this...
while (!document.ready) {
  Thread.sleep(0);
}
Mo’ Threads...
Nested Spaghetti
mainWindow.menu("File", function(err, file) {
  if(err) throw err;
  file.openMenu(function(err, menu) {
    if(err) throw err;
    menu.item("Open", function(err, item) {
      if(err) throw err;
      item.click(function(err) {
        if(err) throw err;
        window.createDialog('DOOM!', function(err, dialog) {
          if(err) throw err;
          ...
        });
      });
    });
  });
});
Inflexible APIs
function launchRocketAt(target, callback) {
  var rocket = {x: 0, y: 0},
      step = 0;

    function moveRocket() {
      rocket.x += target.x * (step / 10);
      rocket.y += target.y * (step / 10);
      drawSprite(rocket);
      if (step === 10) {
        callback();
      } else {
        step += 1;
        setTimeout(moveRocket, 50);
      }
    }

    moveRocket();
}
Inflexible APIs


launchRocketAt(target, function() {
  // OK, so the rocket reached its target...
});
Pattern I: PubSub
What is PubSub?

button.on("click", function(event) {
  ...
});


server.on("request", function(req, res, next) {
  ...
});


model.on("change", function() {
  ...
});
What is PubSub for?


• Just about everything!
• When in doubt, use PubSub
How to use it?

• Pick a PubSub library, such as
  https://github.com/Wolfy87/EventEmitter
• If you’re on Node, you already have one
• Simply make your objects inherit from
  EventEmitter, and trigger events on them
An Evented Rocket
Rocket.prototype.launchAt = function(target) {
  rocket = this;
  _.extend(rocket, {x: 0, y: 0, step: 0});

    function moveRocket() {
      // Physics calculations go here...
      if (rocket.step === 10) {
        rocket.emit('complete', rocket);
      } else {
        rock.step += 1;
        setTimeout(moveRocket, 50);
      }
      rocket.emit('moved', rocket);
    }

    rocket.emit('launched', rocket);
    moveRocket();
    return this;
}
An Evented Rocket


var rocket = new Rocket();
rocket.launchAt(target).on('complete', function() {
  // Now it’s obvious what this callback is!
});
PubSub Drawbacks

• No standard
 • Consider using LucidJS:
   https://github.com/RobertWHurst/
   LucidJS
Pattern II: Promises
What is a Promise?

• “A promise represents the eventual value
  returned from the single completion of an
  operation.”
  —The Promises/A Spec
What is a Promise?
• An object that emits an event when an
  async task completes (or fails)


                      Resolved



           Pending



                      Rejected
Example 1: Ajax

var fetchingData = $.get('myData');
fetchingData.done(onSuccess);
fetchingData.fail(onFailure);
fetchingData.state(); // 'pending'

// Additional listeners can be added at any time
fetchingData.done(celebrate);

// `then` is syntactic sugar for done + fail
fetchingData.then(huzzah, alas);
Example 2: Effects

$('#header').fadeTo('fast', 0.5).slideUp('fast');
$('#content').fadeIn('slow');
var animating = $('#header, #content').promise();

animating.done(function() {
  // All of the animations started when promise()
  // was called are now complete.
});
What is a Promise?
• “A promise is a container for an as-yet-
  unknown value, and then’s job is to
  extract the value out of the promise”

  http://blog.jcoglan.com/2013/03/30/
  callbacks-are-imperative-promises-are-
  functional-nodes-biggest-missed-
  opportunity/
Making Promises

// A Promise is a read-only copy of a Deferred
var deferred = $.Deferred();
asyncRead(function(err, data) {
  if (err) {
     deferred.reject();
  } else {
     deferred.resolve(data);
  };
});
var Promise = deferred.promise();
Without Promises
$.fn.loadAndShowContent(function(options) {
  var $el = this;
  function successHandler(content) {
    $el.html(content);
    options.success(content);
  }
  function errorHandler(err) {
    $el.html('Error');
    options.failure(err);
  }
  $.ajax(options.url, {
    success: successHandler,
    error: errorHandler
  });
});
With Promises
$.fn.loadAndShowContent(function(options) {
  var $el = this,
      fetchingContent = $.ajax(options.url);

  fetchingContent.done(function(content) {
    $el.html(content);
  });

  fetchingContent.fail(function(content) {
    $el.html('Error');
  });

  return fetchingContent;
});
Merging Promises

var fetchingData = $.get('myData');
var fadingButton = $button.fadeOut().promise();

$.when(fetchingData, fadingButton)
 .then(function() {
  // Both Promises have resolved
});
Piping Promises

var fetchingPassword = $.get('/password');
fetchingPassword.done(function(password) {
  var loggingIn = $.post('/login', password);
});

// I wish I could attach listeners to the loggingIn
// Promise here... but it doesn’t exist yet!
Piping Promises
var fetchingPassword = $.get('/password');
var loggingIn = fetchingPassword.pipe(function(password) {
  return $.post('/login', password);
});

loggingIn.then(function() {
  // We’ve logged in successfully
}, function(err) {
  // Either the login failed, or the password fetch failed
});

// NOTE: As of jQuery 1.8, then and pipe are synonymous.
// Use `then` for piping if possible.
Piping Promises
var menuFilePromise = mainWindow.menu('file');
var openFilePromise = menuFilePromise.pipe(function(file) {
  return file.openMenu();
});
var menuOpenPromise = openFilePromise.pipe(function(menu) {
  return menu.item('open');
});
var itemClickPromise = menuOpenPromise.pipe(function(item) {
  return item.click()
});
var createDialogPromise = itemClickPromise.pipe(function() {
  return window.createDialog("Promises rock!");
});
A Promise-y Rocket
function launchRocketAt(target) {
  var rocketDeferred = $.Deferred();
  _.extend(rocketDeferred, {x: 0, y: 0, step: 0});

    function moveRocket() {
      // Physics calculations go here...
      rocketDeferred.notify(step / 10);
      if (rocketDeferred.step === 10) {
        rocketDeferred.resolve();
      } else {
        rocketDeferred.step += 1;
        setTimeout(moveRocket, 50);
      }
    }

    moveRocket();
    return rocketDeferred;
}
Promise Drawbacks

• No standard
 • jQuery, Promises/A, Promises/B...
• For maximum benefit, you’ll need
  wrappers all over the place
Pattern III: AMD
What is AMD?

• Asynchronous Module Definition, a spec
• Each module says which modules it needs
• The module’s “factory” is called after all of
  those modules are loaded
What is AMD for?

• Loading dependencies as needed
• Dependency injection (for tests)
• Gating features
How to use AMD

define('myModule', ['jQuery', 'Backbone'],
function($, Backbone) {
  var myModule = {
    // Define some things...
  };

  // If anyone requires this module, they get this object
  return myModule;
});
AMD Drawbacks

• No standard
• Lots of up-front work
• No semantic versioning
• Heavyweight tools (RequireJS)
Alternatives to AMD

• Browserify
 • Simple syntax:   require('./filename');

 • Great if you’re into Node + npm
 • Intended for bundling, not so much for
   async module loading
Conclusion


• The next time you’re about to define a
  function with a callback argument... don’t.
Thanks. Questions?
     @trevorburnham

Contenu connexe

Tendances

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSVisual Engineering
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS InternalEyal Vardi
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing optionsNir Kaufman
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIVisual Engineering
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular jsAndrew Alpert
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.jsJay Phelps
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)Igor Bronovskyy
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법Jeado Ko
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0Takuya Tejima
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorialClaude Tech
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widgetTudor Barbu
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.jsTechExeter
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.jsBert Wijnants
 
An introduction to Ember.js
An introduction to Ember.jsAn introduction to Ember.js
An introduction to Ember.jscodeofficer
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developersKai Koenig
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIVisual Engineering
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 

Tendances (20)

Workshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJSWorkshop 27: Isomorphic web apps with ReactJS
Workshop 27: Isomorphic web apps with ReactJS
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
Angular js routing options
Angular js routing optionsAngular js routing options
Angular js routing options
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
Workshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte IIIWorkshop 14: AngularJS Parte III
Workshop 14: AngularJS Parte III
 
Building scalable applications with angular js
Building scalable applications with angular jsBuilding scalable applications with angular js
Building scalable applications with angular js
 
Intro to Ember.JS 2016
Intro to Ember.JS 2016Intro to Ember.JS 2016
Intro to Ember.JS 2016
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.js
 
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
09 - express nodes on the right angle - vitaliy basyuk - it event 2013 (5)
 
[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법[FEConf Korea 2017]Angular 컴포넌트 대화법
[FEConf Korea 2017]Angular 컴포넌트 대화법
 
How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0How to Build SPA with Vue Router 2.0
How to Build SPA with Vue Router 2.0
 
Angular JS blog tutorial
Angular JS blog tutorialAngular JS blog tutorial
Angular JS blog tutorial
 
Building a js widget
Building a js widgetBuilding a js widget
Building a js widget
 
Enjoy the vue.js
Enjoy the vue.jsEnjoy the vue.js
Enjoy the vue.js
 
Viking academy backbone.js
Viking academy  backbone.jsViking academy  backbone.js
Viking academy backbone.js
 
An introduction to Ember.js
An introduction to Ember.jsAn introduction to Ember.js
An introduction to Ember.js
 
AngularJS for designers and developers
AngularJS for designers and developersAngularJS for designers and developers
AngularJS for designers and developers
 
AngularJs
AngularJsAngularJs
AngularJs
 
Workshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte IIWorkshop 13: AngularJS Parte II
Workshop 13: AngularJS Parte II
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 

En vedette

Кратчайшая история JavaScript
Кратчайшая история JavaScriptКратчайшая история JavaScript
Кратчайшая история JavaScriptPavel Klimiankou
 
Web advanced-11-d3 js
Web advanced-11-d3 jsWeb advanced-11-d3 js
Web advanced-11-d3 jsStudiabo
 
Web advanced-01-asincrono
Web advanced-01-asincronoWeb advanced-01-asincrono
Web advanced-01-asincronoStudiabo
 
Designers from Hell / Freelance Day 2015
Designers from Hell / Freelance Day 2015Designers from Hell / Freelance Day 2015
Designers from Hell / Freelance Day 2015Sketchin
 

En vedette (6)

Extending Boomerang
Extending BoomerangExtending Boomerang
Extending Boomerang
 
Кратчайшая история JavaScript
Кратчайшая история JavaScriptКратчайшая история JavaScript
Кратчайшая история JavaScript
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Web advanced-11-d3 js
Web advanced-11-d3 jsWeb advanced-11-d3 js
Web advanced-11-d3 js
 
Web advanced-01-asincrono
Web advanced-01-asincronoWeb advanced-01-asincrono
Web advanced-01-asincrono
 
Designers from Hell / Freelance Day 2015
Designers from Hell / Freelance Day 2015Designers from Hell / Freelance Day 2015
Designers from Hell / Freelance Day 2015
 

Similaire à Sane Async Patterns

JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)Domenic Denicola
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Loadrunner
LoadrunnerLoadrunner
Loadrunnerdanwrong
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern偉格 高
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}.toster
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for JoomlaLuke Summerfield
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: ServersidenessWebExpo
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Jason Lotito
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
The evolution of java script asynchronous calls
The evolution of java script asynchronous callsThe evolution of java script asynchronous calls
The evolution of java script asynchronous callsHuy Hoàng Phạm
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Async js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgariaAsync js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgariaHackBulgaria
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularErik Guzman
 

Similaire à Sane Async Patterns (20)

JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Loadrunner
LoadrunnerLoadrunner
Loadrunner
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}Matthew Eernisse, NodeJs, .toster {webdev}
Matthew Eernisse, NodeJs, .toster {webdev}
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Javascript Frameworks for Joomla
Javascript Frameworks for JoomlaJavascript Frameworks for Joomla
Javascript Frameworks for Joomla
 
Douglas Crockford: Serversideness
Douglas Crockford: ServersidenessDouglas Crockford: Serversideness
Douglas Crockford: Serversideness
 
Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13Load Testing with PHP and RedLine13
Load Testing with PHP and RedLine13
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
NodeJS
NodeJSNodeJS
NodeJS
 
Java script for web developer
Java script for web developerJava script for web developer
Java script for web developer
 
The evolution of java script asynchronous calls
The evolution of java script asynchronous callsThe evolution of java script asynchronous calls
The evolution of java script asynchronous calls
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Async js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgariaAsync js - Nemetschek Presentaion @ HackBulgaria
Async js - Nemetschek Presentaion @ HackBulgaria
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & Angular
 
You promise?
You promise?You promise?
You promise?
 

Dernier

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 

Dernier (20)

"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 

Sane Async Patterns

  • 1. Sane Async Patterns Trevor Burnham HTML5DevConf 2013
  • 6. In This Talk • Callback arguments considered harmful • Three alternative patterns: • PubSub • Promises • AMD
  • 7. The Callback Argument Anti-Pattern
  • 8. Pyramid of Doom mainWindow.menu("File", function(err, file) {   if(err) throw err;   file.openMenu(function(err, menu) {     if(err) throw err;     menu.item("Open", function(err, item) {       if(err) throw err;       item.click(function(err) {         if(err) throw err;         window.createDialog('DOOM!', function(err, dialog) {           if(err) throw err;           ...         });       });     });   }); });
  • 9. A JS-er’s Lament // Synchronous version of previous slide try { var file = mainWindow.menu("File");   var menu = file.openMenu();   var item = menu.item("Open");   item.click()   window.createDialog('DOOM!'); } catch (err) { ... }
  • 10. A Silver Lining myFunction1(); // No state changes here! myFunction2(); // Which means we never have to do this... while (!document.ready) { Thread.sleep(0); }
  • 12. Nested Spaghetti mainWindow.menu("File", function(err, file) {   if(err) throw err;   file.openMenu(function(err, menu) {     if(err) throw err;     menu.item("Open", function(err, item) {       if(err) throw err;       item.click(function(err) {         if(err) throw err;         window.createDialog('DOOM!', function(err, dialog) {           if(err) throw err;           ...         });       });     });   }); });
  • 13. Inflexible APIs function launchRocketAt(target, callback) { var rocket = {x: 0, y: 0}, step = 0; function moveRocket() { rocket.x += target.x * (step / 10); rocket.y += target.y * (step / 10); drawSprite(rocket); if (step === 10) { callback(); } else { step += 1; setTimeout(moveRocket, 50); } } moveRocket(); }
  • 14. Inflexible APIs launchRocketAt(target, function() { // OK, so the rocket reached its target... });
  • 16. What is PubSub? button.on("click", function(event) { ... }); server.on("request", function(req, res, next) { ... }); model.on("change", function() { ... });
  • 17. What is PubSub for? • Just about everything! • When in doubt, use PubSub
  • 18. How to use it? • Pick a PubSub library, such as https://github.com/Wolfy87/EventEmitter • If you’re on Node, you already have one • Simply make your objects inherit from EventEmitter, and trigger events on them
  • 19. An Evented Rocket Rocket.prototype.launchAt = function(target) { rocket = this; _.extend(rocket, {x: 0, y: 0, step: 0}); function moveRocket() { // Physics calculations go here... if (rocket.step === 10) { rocket.emit('complete', rocket); } else { rock.step += 1; setTimeout(moveRocket, 50); } rocket.emit('moved', rocket); } rocket.emit('launched', rocket); moveRocket(); return this; }
  • 20. An Evented Rocket var rocket = new Rocket(); rocket.launchAt(target).on('complete', function() { // Now it’s obvious what this callback is! });
  • 21. PubSub Drawbacks • No standard • Consider using LucidJS: https://github.com/RobertWHurst/ LucidJS
  • 23. What is a Promise? • “A promise represents the eventual value returned from the single completion of an operation.” —The Promises/A Spec
  • 24. What is a Promise? • An object that emits an event when an async task completes (or fails) Resolved Pending Rejected
  • 25. Example 1: Ajax var fetchingData = $.get('myData'); fetchingData.done(onSuccess); fetchingData.fail(onFailure); fetchingData.state(); // 'pending' // Additional listeners can be added at any time fetchingData.done(celebrate); // `then` is syntactic sugar for done + fail fetchingData.then(huzzah, alas);
  • 26. Example 2: Effects $('#header').fadeTo('fast', 0.5).slideUp('fast'); $('#content').fadeIn('slow'); var animating = $('#header, #content').promise(); animating.done(function() { // All of the animations started when promise() // was called are now complete. });
  • 27. What is a Promise? • “A promise is a container for an as-yet- unknown value, and then’s job is to extract the value out of the promise” http://blog.jcoglan.com/2013/03/30/ callbacks-are-imperative-promises-are- functional-nodes-biggest-missed- opportunity/
  • 28. Making Promises // A Promise is a read-only copy of a Deferred var deferred = $.Deferred(); asyncRead(function(err, data) { if (err) { deferred.reject(); } else { deferred.resolve(data); }; }); var Promise = deferred.promise();
  • 29. Without Promises $.fn.loadAndShowContent(function(options) { var $el = this; function successHandler(content) { $el.html(content); options.success(content); } function errorHandler(err) { $el.html('Error'); options.failure(err); } $.ajax(options.url, { success: successHandler, error: errorHandler }); });
  • 30. With Promises $.fn.loadAndShowContent(function(options) { var $el = this, fetchingContent = $.ajax(options.url); fetchingContent.done(function(content) { $el.html(content); }); fetchingContent.fail(function(content) { $el.html('Error'); }); return fetchingContent; });
  • 31. Merging Promises var fetchingData = $.get('myData'); var fadingButton = $button.fadeOut().promise(); $.when(fetchingData, fadingButton) .then(function() { // Both Promises have resolved });
  • 32. Piping Promises var fetchingPassword = $.get('/password'); fetchingPassword.done(function(password) { var loggingIn = $.post('/login', password); }); // I wish I could attach listeners to the loggingIn // Promise here... but it doesn’t exist yet!
  • 33. Piping Promises var fetchingPassword = $.get('/password'); var loggingIn = fetchingPassword.pipe(function(password) { return $.post('/login', password); }); loggingIn.then(function() { // We’ve logged in successfully }, function(err) { // Either the login failed, or the password fetch failed }); // NOTE: As of jQuery 1.8, then and pipe are synonymous. // Use `then` for piping if possible.
  • 34. Piping Promises var menuFilePromise = mainWindow.menu('file'); var openFilePromise = menuFilePromise.pipe(function(file) {   return file.openMenu(); }); var menuOpenPromise = openFilePromise.pipe(function(menu) {   return menu.item('open'); }); var itemClickPromise = menuOpenPromise.pipe(function(item) {   return item.click() }); var createDialogPromise = itemClickPromise.pipe(function() {   return window.createDialog("Promises rock!"); });
  • 35. A Promise-y Rocket function launchRocketAt(target) { var rocketDeferred = $.Deferred(); _.extend(rocketDeferred, {x: 0, y: 0, step: 0}); function moveRocket() { // Physics calculations go here... rocketDeferred.notify(step / 10); if (rocketDeferred.step === 10) { rocketDeferred.resolve(); } else { rocketDeferred.step += 1; setTimeout(moveRocket, 50); } } moveRocket(); return rocketDeferred; }
  • 36. Promise Drawbacks • No standard • jQuery, Promises/A, Promises/B... • For maximum benefit, you’ll need wrappers all over the place
  • 38. What is AMD? • Asynchronous Module Definition, a spec • Each module says which modules it needs • The module’s “factory” is called after all of those modules are loaded
  • 39. What is AMD for? • Loading dependencies as needed • Dependency injection (for tests) • Gating features
  • 40. How to use AMD define('myModule', ['jQuery', 'Backbone'], function($, Backbone) { var myModule = { // Define some things... }; // If anyone requires this module, they get this object return myModule; });
  • 41. AMD Drawbacks • No standard • Lots of up-front work • No semantic versioning • Heavyweight tools (RequireJS)
  • 42. Alternatives to AMD • Browserify • Simple syntax: require('./filename'); • Great if you’re into Node + npm • Intended for bundling, not so much for async module loading
  • 43. Conclusion • The next time you’re about to define a function with a callback argument... don’t.
  • 44. Thanks. Questions? @trevorburnham