SlideShare a Scribd company logo
Promises, Promises
                     BY @DOMENIC
Domenic Denicola
•   http://domenic.me
•   https://github.com/domenic
•   https://npmjs.org/~domenic
•   http://slideshare.net/domenicdenicola

Things I’m doing:
• @esdiscuss on Twitter
• The Promises/A+ spec
• HTML5DevConf, NodePDX, NodeConf
                                            @DOMENIC
@DOMENIC
Callbacks are a hack
• They are literally the simplest thing that could work.
• But as a replacement for synchronous control flow, they suck.

• There’s no consistency in callback APIs.
• There’s no guarantees.
• We lose the flow of our code writing callbacks that tie
  together other callbacks.
• We lose the stack-unwinding semantics of exceptions, forcing
  us to handle errors explicitly at every step.
                                                                  @DOMENIC
Promises are the right abstraction
Instead of calling a passed callback, return a promise:

 readFile("file.txt", function (err, result) {
     // continue here…
 });

// becomes

 var promiseForResult = readFile("file.txt");

                                                          @DOMENIC
Promise guarantees
promiseForResult.then(onFulfilled, onRejected);

• Only one of onFulfilled or onRejected will be called.
• onFulfilled will be called with a single fulfillment value (⇔ return value).
• onRejected will be called with a single rejection reason (⇔ thrown exception).
• If the promise is already settled, the handlers will still be called once you
  attach them.
• The handlers will always be called asynchronously.

                                                                       @DOMENIC
Promises can be chained
var transformedPromise = originalPromise.then(onFulfilled, onRejected);

• If the called handler returns a value, transformedPromise will be resolved
  with that value:
  ▫ If the returned value is a promise, we adopt its state.
  ▫ Otherwise, transformedPromise is fulfilled with that value.
• If the called handler throws an exception, transformedPromise will be
  rejected with that exception.

                                                                       @DOMENIC
The Sync ⇔ Async Parallel
 var result, threw = false;

 try {
    result = doSomethingSync();   doSomethingAsync().then(
 } catch (ex) {                      process,
    threw = true;                    handle
    handle(ex);                   );
 }

 if (!threw) process(result);
                                                             @DOMENIC
Case 1: Simple Functional Transform
 var user = getUser();
 var userName = user.name;

// becomes

 var userNamePromise = getUser().then(function (user) {
     return user.name;
 });


                                                          @DOMENIC
Case 2: Reacting with an Exception
 var user = getUser();
 if (user === null)
    throw new Error("null user!");

becomes

 var userPromise = getUser().then(function (user) {
     if (user === null)
        throw new Error("null user!");
     return user;
 });
                                                      @DOMENIC
Case 3: Handling an Exception
 try {
    updateUser(data);
 } catch (ex) {
    console.log("There was an error:", ex);
 }

// becomes

 var updatePromise = updateUser(data).then(undefined, function (ex) {
     console.log("There was an error:", ex);
 });
                                                                    @DOMENIC
Case 4: Rethrowing an Exception
 try {
    updateUser(data);
 } catch (ex) {
    throw new Error("Updating user failed. Details: " + ex.message);
 }

// becomes

 var updatePromise = updateUser(data).then(undefined, function (ex) {
     throw new Error("Updating user failed. Details: " + ex.message);
 });
                                                                       @DOMENIC
Bonus Async Case: Waiting
 var name = promptForNewUserName();
 updateUser({ name: name });
 refreshUI();

// becomes

 promptForNewUserName()
   .then(function (name) {
      return updateUser({ name: name });
   })
   .then(refreshUI);
                                           @DOMENIC
Promises Give You Back Exception Propagation
getUser("Domenic", function (user) {
    getBestFriend(user, function (friend) {
        ui.showBestFriend(friend);
    });
});




                                               @DOMENIC
Promises Give You Back Exception Propagation
getUser("Domenic", function (err, user) {
    if (err) {
       ui.error(err);
    } else {
       getBestFriend(user, function (err, friend) {
           if (err) {
              ui.error(err);
           } else {
              ui.showBestFriend(friend);
           }
       });
    }
});
                                                      @DOMENIC
Promises Give You Back Exception Propagation
getUser("Domenic")
  .then(getBestFriend)
  .then(ui.showBestFriend, ui.error);




                                               @DOMENIC
Promises as First-Class Objects
• Because promises are first-class objects, you can build simple operations on
  them instead of tying callbacks together:

// Fulfills with an array of results, or rejects if any reject
all([getUserData(), getCompanyData()]);

// Fulfills as soon as either completes, or rejects if both reject
any([storeDataOnServer1(), storeDataOnServer2()]);

// If writeFile accepts promises as arguments, and readFile returns one:
writeFile("dest.txt", readFile("source.txt"));
                                                                           @DOMENIC
@DOMENIC
Prehistory
• “Discovered” circa 1989.
• Much of modern promises are inspired by the E programming language.
• They’ve made their way into many languages:
 ▫   .NET’s Task<T>
 ▫   java.util.concurrent.Future
 ▫   Python’s PEP 3148
 ▫   C++ 11’s std::future


                                                              @DOMENIC
CommonJS Promises/A
• Inspired by early implementations: ref_send, Dojo, …
• But…
  ▫ Underspecified
  ▫ Missing key features
  ▫ Often misinterpreted




                                                         @DOMENIC
$.Deferred
jQuery’s $.Deferred is a very buggy attempted implementation, that
entirely misses the sync ⇔ async parallel:
• Multiple fulfillment values and rejection reasons
• Only supports scenario 1 (functional transformation); doesn’t handle
  errors
• Not interoperable with other “thenables.”
• Before 1.8, did not support returning a promise


                                                                 @DOMENIC
All Was Quiet, Until…




                        HORRIBLE LIES!!




                                          @DOMENIC
I Got Angry




              @DOMENIC
Then I Did Something About It




                                @DOMENIC
@DOMENIC
Then Things Got Awesome




                          @DOMENIC
Fast-Forward a Few Months…




                             @DOMENIC
I Think It’s Been a Success
• >20 conformant implementations, with more showing up constantly
  ▫ Even one in ActionScript 3!
• The creation of RSVP.js specifically so that Ember could have
  Promises/A+ compatible promises
• Version 1.1 of the spec almost ready, nailing down some unspecified
  points
• Several other sibling specs under active development: promise creation,
  cancellation, progress, …

                                                                 @DOMENIC
Even the DOM and TC39 are getting in on this
• Alex Russell’s DOMFuture promise library, for possibly using promises in
  future or existing DOM APIs
• Convergence with Mark Miller’s concurrency strawman, for integrating
  promises into the language




                                                                  @DOMENIC
Some practical guidance




                          @DOMENIC
First, Choose a Library
• My top picks:
  ▫ Q, by Kris Kowal and myself: https://github.com/kriskowal/q
  ▫ When.js, by Brian Cavalier: https://github.com/cujojs/when
  ▫ RSVP.js, by Yehuda Katz: https://github.com/tildeio/rsvp.js

• If you ever see a jQuery promise, kill it with fire:

 var realPromise = Q(jQueryPromise);
 var realPromise = when(jQueryPromise);
                                                                  @DOMENIC
Keep The Sync ⇔ Async Parallel In Mind
• Use promises for single operations that can result in fulfillment
  (⇔ returning a value) or rejection (⇔ throwing an exception).

• If you’re ever stuck, ask “how would I structure this code if it
  were synchronous?”
  ▫ The only exception is multiple parallel operations, which has no
    sync counterpart.


                                                                       @DOMENIC
Promises Are Not
• A replacement for events
• A replacement for streams
• A way of doing functional reactive programming

They work together:
• An event can trigger from one part of your UI, causing the event handler
  to trigger a promise-returning function
• A HTTP request function can return a promise for a stream

                                                                  @DOMENIC
The Unhandled Rejection Pitfall
This hits the top of the stack:

 throw new Error("boo!");

This stays inert:

 var promise = doSomething().then(function () {
     throw new Error("boo!");
 });

                                                  @DOMENIC
Avoiding the Unhandled Rejection Pitfall
• Always either:
  ▫ return the promise to your caller;
  ▫ or call .done() on it to signal that any unhandled rejections should explode

function getUserName() {
   return getUser().then(function (user) {
    return user.name;
   });
 }
 getUserName().then(function (userName) {
    console.log("User name: ", userName);
 }).done();                                                                   @DOMENIC
Promise Patterns: try/catch/finally
ui.startSpinner();
getUser("Domenic")
   .then(getBestFriend)
   .then(ui.showBestFriend)
   .catch(ui.error)
   .finally(ui.stopSpinner)
   .done();



                                      @DOMENIC
Promise Patterns: all + spread
Q.all([getUser(), getCompany()]).then(function (results) {
   console.log("user = ", results[0]);
   console.log("company = ", results[1]);
}).done();

Q.all([getUser(), getCompany()]).spread(function (user, company) {
   console.log("user = ", user);
   console.log("company = ", company);
}).done();
                                                                 @DOMENIC
Promise Patterns: map + all
var userIds = ["123", "456", "789"];

Q.all(userIds.map(getUserById))
  .then(function (users) {
     console.log("all the users: ", users);
  })
  .done();


                                              @DOMENIC
Promise Patterns: message sending
var userData = getUserData();
userData
  .then(createUserViewModel)
  .invoke("setStatus", "loaded")
  .done();
userData
  .get("friends")
  .get("0")
  .get("name")
  .then(setBestFriendsNameInUI)
  .done();
                                    @DOMENIC
Promise Patterns: Denodeify
var readFile = Q.denodeify(fs.readFile);
var readDir = Q.denodeify(fs.readdir);
readDir("/tmp")
  .get("0")
  .then(readFile)
  .then(function (data) {
     console.log("The first temporary file contains: ", data);
  })
  .catch(function (error) {
     console.log("One of the steps failed: ", error);
  })
  .done();
                                                                 @DOMENIC
(Bonus round!)




                 @DOMENIC
Coroutines

    “Coroutines are computer program
components that generalize subroutines to
allow multiple entry points for suspending
     and resuming execution at certain
                locations.”
                                     @DOMENIC
Generators = Shallow Coroutines
function* fibonacci() {
  var [prev, curr] = [0, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (n of fibonnaci()) {
  console.log(n);
}                                         @DOMENIC
http://taskjs.org/


task.js: Generators + Promises = Tasks
spawn(function* () {
    var data = yield $.ajax(url);
    $("#result").html(data);
    var status = $("#status").html("Download complete.");
    yield status.fadeIn().promise();
    yield sleep(2000);
    status.fadeOut();
});

                                                            @DOMENIC
task.js Even Works on Exceptions
spawn(function* () {
  var user;
  try {
     user = yield getUser();
  } catch (err) {
     ui.showError(err);
     return;
  }

      ui.updateUser(user);
});
                                   @DOMENIC
Remote Promises
userPromise
  .get("friends")
  .get("0")
  .invoke("calculateFriendshipCoefficient")
  .then(displayInUI)
  .done();

What if … userPromise referred to a remote object?!

                                                      @DOMENIC
https://github.com/kriskowal/q-connection/



Q Connection
• Can connect to web workers, <iframe>s, or web sockets

var Q = require("q");
var Connection = require("q-comm");
var remote = Connection(port, local);

// a promise for a remote object!
var userPromise = remote.getUser();


                                                                        @DOMENIC
Promise Pipelining
• Usual “remote object” systems fall down in a few ways:
  ▫ They would see the first request, and return the entire friends array.
  ▫ They can’t invoke methods that involved closed-over state, only methods
    that you can send over the wire.
  ▫ Workarounds involve complex serialization and rehydration approaches, i.e.
    require coupling the client and the server.
• With promises as the abstraction, we can “pipeline” messages from one
  side to the other, returning the ultimately-desired result.

                                                                     @DOMENIC
• Start using promises in your code: client, server,
                everywhere.
              • Be aware that you want a Promises/A+ compatible
                library—beware jQuery.
              • Generators are almost ready in Firefox, Chrome, and
What’s next     Node.js.
              • Investigate promises for real-time communication with
                Q-Connection.
              • Look forward to promises in the DOM, and maybe some
                syntactic support in ECMAScript 7!




                                                          @DOMENIC

More Related Content

What's hot

Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
Yura Nosenko
 
Its time to React.js
Its time to React.jsIts time to React.js
Its time to React.js
Ritesh Mehrotra
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
habib_786
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Spring Security
Spring SecuritySpring Security
Spring Security
Knoldus Inc.
 
Asynchronous javascript
 Asynchronous javascript Asynchronous javascript
Asynchronous javascript
Eman Mohamed
 
React js programming concept
React js programming conceptReact js programming concept
React js programming concept
Tariqul islam
 
Async js
Async jsAsync js
Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022
Fabio Biondi
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
Jeroen Rosenberg
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
Varun Raj
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
Jakub Kubrynski
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
Sandeep Chawla
 
Reactjs workshop
Reactjs workshop Reactjs workshop
Reactjs workshop
Ahmed rebai
 
React Js Simplified
React Js SimplifiedReact Js Simplified
React Js Simplified
Sunil Yadav
 
Spring data presentation
Spring data presentationSpring data presentation
Spring data presentation
Oleksii Usyk
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
Naphachara Rattanawilai
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
Max Claus Nunes
 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8
Richard Walker
 

What's hot (20)

Whitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applicationsWhitebox testing of Spring Boot applications
Whitebox testing of Spring Boot applications
 
Its time to React.js
Its time to React.jsIts time to React.js
Its time to React.js
 
ASP.NET Web API
ASP.NET Web APIASP.NET Web API
ASP.NET Web API
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Spring Security
Spring SecuritySpring Security
Spring Security
 
Asynchronous javascript
 Asynchronous javascript Asynchronous javascript
Asynchronous javascript
 
React js programming concept
React js programming conceptReact js programming concept
React js programming concept
 
Async js
Async jsAsync js
Async js
 
Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022Redux Toolkit - Quick Intro - 2022
Redux Toolkit - Quick Intro - 2022
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
 
Introduction to React JS for beginners
Introduction to React JS for beginners Introduction to React JS for beginners
Introduction to React JS for beginners
 
Introduction to Spring Boot!
Introduction to Spring Boot!Introduction to Spring Boot!
Introduction to Spring Boot!
 
Maven Introduction
Maven IntroductionMaven Introduction
Maven Introduction
 
Reactjs workshop
Reactjs workshop Reactjs workshop
Reactjs workshop
 
React Js Simplified
React Js SimplifiedReact Js Simplified
React Js Simplified
 
Spring data presentation
Spring data presentationSpring data presentation
Spring data presentation
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Flask – Python
Flask – PythonFlask – Python
Flask – Python
 
Optional in Java 8
Optional in Java 8Optional in Java 8
Optional in Java 8
 

Viewers also liked

JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
Joseph Chiang
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was Born
Domenic Denicola
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
Łukasz Kużyński
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
Domenic Denicola
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
Solution4Future
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
우영 주
 
The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)
Domenic Denicola
 
How to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesHow to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards Bodies
Domenic Denicola
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
Tomasz Bak
 
Promises
Promises Promises
Promises
Amal Haque
 
Present Simple With Future Meaning
Present Simple With Future MeaningPresent Simple With Future Meaning
Present Simple With Future Meaning
josealmaraz1999
 
Talking about the Future using Present Tenses
Talking about the Future using Present TensesTalking about the Future using Present Tenses
Talking about the Future using Present Tenses
theLecturette
 
Promises Javascript
Promises JavascriptPromises Javascript
Promises Javascript
Julien CROUZET
 
Real World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScript
Domenic Denicola
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
Creating Truly RESTful APIs
Creating Truly RESTful APIsCreating Truly RESTful APIs
Creating Truly RESTful APIs
Domenic Denicola
 
Present tense verbs with future meaning
Present tense verbs with future meaningPresent tense verbs with future meaning
Present tense verbs with future meaning
maleja2028
 
The Final Frontier
The Final FrontierThe Final Frontier
The Final Frontier
Domenic Denicola
 
Client-Side Packages
Client-Side PackagesClient-Side Packages
Client-Side Packages
Domenic Denicola
 
Importance of contract in Islam and legal importance
Importance of contract in Islam and legal importanceImportance of contract in Islam and legal importance
Importance of contract in Islam and legal importance
Muhammad Zeeshan Baloch
 

Viewers also liked (20)

JavaScript Promise
JavaScript PromiseJavaScript Promise
JavaScript Promise
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was Born
 
Callbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascriptCallbacks, promises, generators - asynchronous javascript
Callbacks, promises, generators - asynchronous javascript
 
JavaScript on the Desktop
JavaScript on the DesktopJavaScript on the Desktop
JavaScript on the Desktop
 
JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6JavaScript - new features in ECMAScript 6
JavaScript - new features in ECMAScript 6
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
The State of JavaScript (2015)
The State of JavaScript (2015)The State of JavaScript (2015)
The State of JavaScript (2015)
 
How to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards BodiesHow to Win Friends and Influence Standards Bodies
How to Win Friends and Influence Standards Bodies
 
JavaScript Promises
JavaScript PromisesJavaScript Promises
JavaScript Promises
 
Promises
Promises Promises
Promises
 
Present Simple With Future Meaning
Present Simple With Future MeaningPresent Simple With Future Meaning
Present Simple With Future Meaning
 
Talking about the Future using Present Tenses
Talking about the Future using Present TensesTalking about the Future using Present Tenses
Talking about the Future using Present Tenses
 
Promises Javascript
Promises JavascriptPromises Javascript
Promises Javascript
 
Real World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScriptReal World Windows 8 Apps in JavaScript
Real World Windows 8 Apps in JavaScript
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
Creating Truly RESTful APIs
Creating Truly RESTful APIsCreating Truly RESTful APIs
Creating Truly RESTful APIs
 
Present tense verbs with future meaning
Present tense verbs with future meaningPresent tense verbs with future meaning
Present tense verbs with future meaning
 
The Final Frontier
The Final FrontierThe Final Frontier
The Final Frontier
 
Client-Side Packages
Client-Side PackagesClient-Side Packages
Client-Side Packages
 
Importance of contract in Islam and legal importance
Importance of contract in Islam and legal importanceImportance of contract in Islam and legal importance
Importance of contract in Islam and legal importance
 

Similar to Promises, Promises

Domains!
Domains!Domains!
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
Domenic Denicola
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
Domenic Denicola
 
You promise?
You promise?You promise?
You promise?
IT Weekend
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
TrevorBurnham
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
async_io
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
偉格 高
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
Luciano Mammino
 
Promises look into the async future
Promises look into the async futurePromises look into the async future
Promises look into the async future
slicejs
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
Ivano Malavolta
 
How to keep promises
How to keep promisesHow to keep promises
How to keep promises
Dominique Dumont
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
Domenic Denicola
 
JavaScript
JavaScriptJavaScript
JavaScript
Ivano Malavolta
 
Realm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionRealm Mobile Database - An Introduction
Realm Mobile Database - An Introduction
Knoldus Inc.
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS Promises
Asa Kusuma
 
Web development basics (Part-6)
Web development basics (Part-6)Web development basics (Part-6)
Web development basics (Part-6)
Rajat Pratap Singh
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
Juliana Lucena
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
Ryan Weaver
 
Asynchronous development in JavaScript
Asynchronous development  in JavaScriptAsynchronous development  in JavaScript
Asynchronous development in JavaScript
Amitai Barnea
 
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
Huy Hoàng Phạm
 

Similar to Promises, Promises (20)

Domains!
Domains!Domains!
Domains!
 
The Promised Land (in Angular)
The Promised Land (in Angular)The Promised Land (in Angular)
The Promised Land (in Angular)
 
Unit Testing for Great Justice
Unit Testing for Great JusticeUnit Testing for Great Justice
Unit Testing for Great Justice
 
You promise?
You promise?You promise?
You promise?
 
Sane Async Patterns
Sane Async PatternsSane Async Patterns
Sane Async Patterns
 
Javascript Promises/Q Library
Javascript Promises/Q LibraryJavascript Promises/Q Library
Javascript Promises/Q Library
 
Javascript essential-pattern
Javascript essential-patternJavascript essential-pattern
Javascript essential-pattern
 
An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
 
Promises look into the async future
Promises look into the async futurePromises look into the async future
Promises look into the async future
 
[2015/2016] JavaScript
[2015/2016] JavaScript[2015/2016] JavaScript
[2015/2016] JavaScript
 
How to keep promises
How to keep promisesHow to keep promises
How to keep promises
 
ES6: The Awesome Parts
ES6: The Awesome PartsES6: The Awesome Parts
ES6: The Awesome Parts
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Realm Mobile Database - An Introduction
Realm Mobile Database - An IntroductionRealm Mobile Database - An Introduction
Realm Mobile Database - An Introduction
 
Getting Comfortable with JS Promises
Getting Comfortable with JS PromisesGetting Comfortable with JS Promises
Getting Comfortable with JS Promises
 
Web development basics (Part-6)
Web development basics (Part-6)Web development basics (Part-6)
Web development basics (Part-6)
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
 
Asynchronous development in JavaScript
Asynchronous development  in JavaScriptAsynchronous development  in JavaScript
Asynchronous development in JavaScript
 
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
 

More from Domenic Denicola

Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
Domenic Denicola
 
The jsdom
The jsdomThe jsdom
The jsdom
Domenic Denicola
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
Domenic Denicola
 
Streams for the Web
Streams for the WebStreams for the Web
Streams for the Web
Domenic Denicola
 
After Return of the Jedi
After Return of the JediAfter Return of the Jedi
After Return of the Jedi
Domenic Denicola
 
The State of JavaScript
The State of JavaScriptThe State of JavaScript
The State of JavaScript
Domenic Denicola
 
The Extensible Web
The Extensible WebThe Extensible Web
The Extensible Web
Domenic Denicola
 
Understanding the Node.js Platform
Understanding the Node.js PlatformUnderstanding the Node.js Platform
Understanding the Node.js Platform
Domenic Denicola
 

More from Domenic Denicola (8)

Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
 
The jsdom
The jsdomThe jsdom
The jsdom
 
ES6 in Real Life
ES6 in Real LifeES6 in Real Life
ES6 in Real Life
 
Streams for the Web
Streams for the WebStreams for the Web
Streams for the Web
 
After Return of the Jedi
After Return of the JediAfter Return of the Jedi
After Return of the Jedi
 
The State of JavaScript
The State of JavaScriptThe State of JavaScript
The State of JavaScript
 
The Extensible Web
The Extensible WebThe Extensible Web
The Extensible Web
 
Understanding the Node.js Platform
Understanding the Node.js PlatformUnderstanding the Node.js Platform
Understanding the Node.js Platform
 

Recently uploaded

Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
Pitangent Analytics & Technology Solutions Pvt. Ltd
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
Jason Packer
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
saastr
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
Pablo Gómez Abajo
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
DianaGray10
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
Neo4j
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
Jakub Marek
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
Edge AI and Vision Alliance
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
Miro Wengner
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
Ajin Abraham
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
Hiroshi SHIBATA
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
Jason Yip
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
Fwdays
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
saastr
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
AstuteBusiness
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Precisely
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
Alex Pruden
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Tosin Akinosho
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
operationspcvita
 

Recently uploaded (20)

Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
Crafting Excellence: A Comprehensive Guide to iOS Mobile App Development Serv...
 
Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024Northern Engraving | Nameplate Manufacturing Process - 2024
Northern Engraving | Nameplate Manufacturing Process - 2024
 
Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024Columbus Data & Analytics Wednesdays - June 2024
Columbus Data & Analytics Wednesdays - June 2024
 
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
Deep Dive: AI-Powered Marketing to Get More Leads and Customers with HyperGro...
 
Mutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented ChatbotsMutation Testing for Task-Oriented Chatbots
Mutation Testing for Task-Oriented Chatbots
 
What is an RPA CoE? Session 1 – CoE Vision
What is an RPA CoE?  Session 1 – CoE VisionWhat is an RPA CoE?  Session 1 – CoE Vision
What is an RPA CoE? Session 1 – CoE Vision
 
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge GraphGraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
GraphRAG for LifeSciences Hands-On with the Clinical Knowledge Graph
 
Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)Main news related to the CCS TSI 2023 (2023/1695)
Main news related to the CCS TSI 2023 (2023/1695)
 
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
“How Axelera AI Uses Digital Compute-in-memory to Deliver Fast and Energy-eff...
 
JavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green MasterplanJavaLand 2024: Application Development Green Masterplan
JavaLand 2024: Application Development Green Masterplan
 
AppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSFAppSec PNW: Android and iOS Application Security with MobSF
AppSec PNW: Android and iOS Application Security with MobSF
 
Introduction of Cybersecurity with OSS at Code Europe 2024
Introduction of Cybersecurity with OSS  at Code Europe 2024Introduction of Cybersecurity with OSS  at Code Europe 2024
Introduction of Cybersecurity with OSS at Code Europe 2024
 
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
[OReilly Superstream] Occupy the Space: A grassroots guide to engineering (an...
 
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk"Frontline Battles with DDoS: Best practices and Lessons Learned",  Igor Ivaniuk
"Frontline Battles with DDoS: Best practices and Lessons Learned", Igor Ivaniuk
 
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
Overcoming the PLG Trap: Lessons from Canva's Head of Sales & Head of EMEA Da...
 
Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |Astute Business Solutions | Oracle Cloud Partner |
Astute Business Solutions | Oracle Cloud Partner |
 
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their MainframeDigital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
Digital Banking in the Cloud: How Citizens Bank Unlocked Their Mainframe
 
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
zkStudyClub - LatticeFold: A Lattice-based Folding Scheme and its Application...
 
Monitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdfMonitoring and Managing Anomaly Detection on OpenShift.pdf
Monitoring and Managing Anomaly Detection on OpenShift.pdf
 
The Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptxThe Microsoft 365 Migration Tutorial For Beginner.pptx
The Microsoft 365 Migration Tutorial For Beginner.pptx
 

Promises, Promises

  • 1. Promises, Promises BY @DOMENIC
  • 2. Domenic Denicola • http://domenic.me • https://github.com/domenic • https://npmjs.org/~domenic • http://slideshare.net/domenicdenicola Things I’m doing: • @esdiscuss on Twitter • The Promises/A+ spec • HTML5DevConf, NodePDX, NodeConf @DOMENIC
  • 4. Callbacks are a hack • They are literally the simplest thing that could work. • But as a replacement for synchronous control flow, they suck. • There’s no consistency in callback APIs. • There’s no guarantees. • We lose the flow of our code writing callbacks that tie together other callbacks. • We lose the stack-unwinding semantics of exceptions, forcing us to handle errors explicitly at every step. @DOMENIC
  • 5. Promises are the right abstraction Instead of calling a passed callback, return a promise: readFile("file.txt", function (err, result) { // continue here… }); // becomes var promiseForResult = readFile("file.txt"); @DOMENIC
  • 6. Promise guarantees promiseForResult.then(onFulfilled, onRejected); • Only one of onFulfilled or onRejected will be called. • onFulfilled will be called with a single fulfillment value (⇔ return value). • onRejected will be called with a single rejection reason (⇔ thrown exception). • If the promise is already settled, the handlers will still be called once you attach them. • The handlers will always be called asynchronously. @DOMENIC
  • 7. Promises can be chained var transformedPromise = originalPromise.then(onFulfilled, onRejected); • If the called handler returns a value, transformedPromise will be resolved with that value: ▫ If the returned value is a promise, we adopt its state. ▫ Otherwise, transformedPromise is fulfilled with that value. • If the called handler throws an exception, transformedPromise will be rejected with that exception. @DOMENIC
  • 8. The Sync ⇔ Async Parallel var result, threw = false; try { result = doSomethingSync(); doSomethingAsync().then( } catch (ex) { process, threw = true; handle handle(ex); ); } if (!threw) process(result); @DOMENIC
  • 9. Case 1: Simple Functional Transform var user = getUser(); var userName = user.name; // becomes var userNamePromise = getUser().then(function (user) { return user.name; }); @DOMENIC
  • 10. Case 2: Reacting with an Exception var user = getUser(); if (user === null) throw new Error("null user!"); becomes var userPromise = getUser().then(function (user) { if (user === null) throw new Error("null user!"); return user; }); @DOMENIC
  • 11. Case 3: Handling an Exception try { updateUser(data); } catch (ex) { console.log("There was an error:", ex); } // becomes var updatePromise = updateUser(data).then(undefined, function (ex) { console.log("There was an error:", ex); }); @DOMENIC
  • 12. Case 4: Rethrowing an Exception try { updateUser(data); } catch (ex) { throw new Error("Updating user failed. Details: " + ex.message); } // becomes var updatePromise = updateUser(data).then(undefined, function (ex) { throw new Error("Updating user failed. Details: " + ex.message); }); @DOMENIC
  • 13. Bonus Async Case: Waiting var name = promptForNewUserName(); updateUser({ name: name }); refreshUI(); // becomes promptForNewUserName() .then(function (name) { return updateUser({ name: name }); }) .then(refreshUI); @DOMENIC
  • 14. Promises Give You Back Exception Propagation getUser("Domenic", function (user) { getBestFriend(user, function (friend) { ui.showBestFriend(friend); }); }); @DOMENIC
  • 15. Promises Give You Back Exception Propagation getUser("Domenic", function (err, user) { if (err) { ui.error(err); } else { getBestFriend(user, function (err, friend) { if (err) { ui.error(err); } else { ui.showBestFriend(friend); } }); } }); @DOMENIC
  • 16. Promises Give You Back Exception Propagation getUser("Domenic") .then(getBestFriend) .then(ui.showBestFriend, ui.error); @DOMENIC
  • 17. Promises as First-Class Objects • Because promises are first-class objects, you can build simple operations on them instead of tying callbacks together: // Fulfills with an array of results, or rejects if any reject all([getUserData(), getCompanyData()]); // Fulfills as soon as either completes, or rejects if both reject any([storeDataOnServer1(), storeDataOnServer2()]); // If writeFile accepts promises as arguments, and readFile returns one: writeFile("dest.txt", readFile("source.txt")); @DOMENIC
  • 19. Prehistory • “Discovered” circa 1989. • Much of modern promises are inspired by the E programming language. • They’ve made their way into many languages: ▫ .NET’s Task<T> ▫ java.util.concurrent.Future ▫ Python’s PEP 3148 ▫ C++ 11’s std::future @DOMENIC
  • 20. CommonJS Promises/A • Inspired by early implementations: ref_send, Dojo, … • But… ▫ Underspecified ▫ Missing key features ▫ Often misinterpreted @DOMENIC
  • 21. $.Deferred jQuery’s $.Deferred is a very buggy attempted implementation, that entirely misses the sync ⇔ async parallel: • Multiple fulfillment values and rejection reasons • Only supports scenario 1 (functional transformation); doesn’t handle errors • Not interoperable with other “thenables.” • Before 1.8, did not support returning a promise @DOMENIC
  • 22. All Was Quiet, Until… HORRIBLE LIES!! @DOMENIC
  • 23. I Got Angry @DOMENIC
  • 24. Then I Did Something About It @DOMENIC
  • 26. Then Things Got Awesome @DOMENIC
  • 27. Fast-Forward a Few Months… @DOMENIC
  • 28. I Think It’s Been a Success • >20 conformant implementations, with more showing up constantly ▫ Even one in ActionScript 3! • The creation of RSVP.js specifically so that Ember could have Promises/A+ compatible promises • Version 1.1 of the spec almost ready, nailing down some unspecified points • Several other sibling specs under active development: promise creation, cancellation, progress, … @DOMENIC
  • 29. Even the DOM and TC39 are getting in on this • Alex Russell’s DOMFuture promise library, for possibly using promises in future or existing DOM APIs • Convergence with Mark Miller’s concurrency strawman, for integrating promises into the language @DOMENIC
  • 31. First, Choose a Library • My top picks: ▫ Q, by Kris Kowal and myself: https://github.com/kriskowal/q ▫ When.js, by Brian Cavalier: https://github.com/cujojs/when ▫ RSVP.js, by Yehuda Katz: https://github.com/tildeio/rsvp.js • If you ever see a jQuery promise, kill it with fire: var realPromise = Q(jQueryPromise); var realPromise = when(jQueryPromise); @DOMENIC
  • 32. Keep The Sync ⇔ Async Parallel In Mind • Use promises for single operations that can result in fulfillment (⇔ returning a value) or rejection (⇔ throwing an exception). • If you’re ever stuck, ask “how would I structure this code if it were synchronous?” ▫ The only exception is multiple parallel operations, which has no sync counterpart. @DOMENIC
  • 33. Promises Are Not • A replacement for events • A replacement for streams • A way of doing functional reactive programming They work together: • An event can trigger from one part of your UI, causing the event handler to trigger a promise-returning function • A HTTP request function can return a promise for a stream @DOMENIC
  • 34. The Unhandled Rejection Pitfall This hits the top of the stack: throw new Error("boo!"); This stays inert: var promise = doSomething().then(function () { throw new Error("boo!"); }); @DOMENIC
  • 35. Avoiding the Unhandled Rejection Pitfall • Always either: ▫ return the promise to your caller; ▫ or call .done() on it to signal that any unhandled rejections should explode function getUserName() { return getUser().then(function (user) { return user.name; }); } getUserName().then(function (userName) { console.log("User name: ", userName); }).done(); @DOMENIC
  • 36. Promise Patterns: try/catch/finally ui.startSpinner(); getUser("Domenic") .then(getBestFriend) .then(ui.showBestFriend) .catch(ui.error) .finally(ui.stopSpinner) .done(); @DOMENIC
  • 37. Promise Patterns: all + spread Q.all([getUser(), getCompany()]).then(function (results) { console.log("user = ", results[0]); console.log("company = ", results[1]); }).done(); Q.all([getUser(), getCompany()]).spread(function (user, company) { console.log("user = ", user); console.log("company = ", company); }).done(); @DOMENIC
  • 38. Promise Patterns: map + all var userIds = ["123", "456", "789"]; Q.all(userIds.map(getUserById)) .then(function (users) { console.log("all the users: ", users); }) .done(); @DOMENIC
  • 39. Promise Patterns: message sending var userData = getUserData(); userData .then(createUserViewModel) .invoke("setStatus", "loaded") .done(); userData .get("friends") .get("0") .get("name") .then(setBestFriendsNameInUI) .done(); @DOMENIC
  • 40. Promise Patterns: Denodeify var readFile = Q.denodeify(fs.readFile); var readDir = Q.denodeify(fs.readdir); readDir("/tmp") .get("0") .then(readFile) .then(function (data) { console.log("The first temporary file contains: ", data); }) .catch(function (error) { console.log("One of the steps failed: ", error); }) .done(); @DOMENIC
  • 41. (Bonus round!) @DOMENIC
  • 42. Coroutines “Coroutines are computer program components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations.” @DOMENIC
  • 43. Generators = Shallow Coroutines function* fibonacci() { var [prev, curr] = [0, 1]; while (true) { [prev, curr] = [curr, prev + curr]; yield curr; } } for (n of fibonnaci()) { console.log(n); } @DOMENIC
  • 44. http://taskjs.org/ task.js: Generators + Promises = Tasks spawn(function* () { var data = yield $.ajax(url); $("#result").html(data); var status = $("#status").html("Download complete."); yield status.fadeIn().promise(); yield sleep(2000); status.fadeOut(); }); @DOMENIC
  • 45. task.js Even Works on Exceptions spawn(function* () { var user; try { user = yield getUser(); } catch (err) { ui.showError(err); return; } ui.updateUser(user); }); @DOMENIC
  • 46. Remote Promises userPromise .get("friends") .get("0") .invoke("calculateFriendshipCoefficient") .then(displayInUI) .done(); What if … userPromise referred to a remote object?! @DOMENIC
  • 47. https://github.com/kriskowal/q-connection/ Q Connection • Can connect to web workers, <iframe>s, or web sockets var Q = require("q"); var Connection = require("q-comm"); var remote = Connection(port, local); // a promise for a remote object! var userPromise = remote.getUser(); @DOMENIC
  • 48. Promise Pipelining • Usual “remote object” systems fall down in a few ways: ▫ They would see the first request, and return the entire friends array. ▫ They can’t invoke methods that involved closed-over state, only methods that you can send over the wire. ▫ Workarounds involve complex serialization and rehydration approaches, i.e. require coupling the client and the server. • With promises as the abstraction, we can “pipeline” messages from one side to the other, returning the ultimately-desired result. @DOMENIC
  • 49. • Start using promises in your code: client, server, everywhere. • Be aware that you want a Promises/A+ compatible library—beware jQuery. • Generators are almost ready in Firefox, Chrome, and What’s next Node.js. • Investigate promises for real-time communication with Q-Connection. • Look forward to promises in the DOM, and maybe some syntactic support in ECMAScript 7! @DOMENIC

Editor's Notes

  1. Hook: how many used promises?jQuery promises or real promises?Want to talk about this in three parts: a ground-up view of the promise abstraction; a historical perspective on recent developments; and a practical guide to using them in your code.
  2. What I really mean by this is “callback-accepting functions are a hack.”
  3. First benefit: separating outputs from inputs.
  4. - Consistency gains: never call back with more than one fulfillment value or rejection reason.
  5. Just like a series of imperative statements.
  6. And yet, we lived with it.
  7. Spec development process through GitHub issue trackerPull requests, implementers weighing in, bugs opened by randoms, etc.Test suite!
  8. Q has:Large, powerful API surfaceAdapters for Node.jsProgress supportSome support for long stack traces