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

A Look at ES6 Promises

A Look at ES6 Promises

In this talk I take a look at ES6 promises, covering the API, a few examples, tips, gotchas, testing techniques, and more. Corresponding content can be found at https://github.com/jimf/es6-promises-talk.

This talk was given to the Bucks County JS meetup on Jan 6, 2016.

Jim Fitzpatrick

January 06, 2016
Tweet

More Decks by Jim Fitzpatrick

Other Decks in Programming

Transcript

  1. Creating a new promise // Create a pending promise instance

    new Promise(function(resolve, reject) { // Perform an async operation });
  2. Creating a new promise // Create a pending promise instance

    new Promise(function(resolve, reject) { // On success, resolve with result resolve(resultData); });
  3. Creating a new promise // Create a pending promise instance

    new Promise(function(resolve, reject) { // On failure, reject with error reject(resultError); });
  4. Promise.race var p1 = new Promise(function(resolve, reject) { setTimeout(resolve, 500,

    'one'); }); var p2 = new Promise(function(resolve, reject) { setTimeout(resolve, 100, 'two'); }); Promise.race([p1, p2]).then(function(value) { console.log(value); // "two" // Both resolve, but p2 is faster });
  5. #1. Coerce jqXHR ($.Deferred) to a Promise new Promise(function(resolve, reject)

    { $.ajax({ url: 'https://randomuser.me/api/', dataType: 'json', success: resolve, error: reject }); });
  6. #2. Wrap setTimeout function wait(delay) { return function(val) { return

    new Promise(function(resolve) { setTimeout(resolve, delay, val); }); }; }
  7. /** * Retrieve account data (if logged in) * *

    @return {undefined} */ fetchAccountData() { if (!this.session.isLoggedIn()) { return; } this.models.account.fetch(); }
  8. #1. Always return the promise /** * Retrieve account data

    (if logged in) * * @return {undefined|Promise} */ fetchAccountData() { if (!this.session.isLoggedIn()) { return; } return this.models.account.fetch(); }
  9. #2. Always be “thenable” /** * Retrieve account data (if

    logged in) * * @return {Promise} */ fetchAccountData() { if (!this.session.isLoggedIn()) { return Promise.reject(new Error('not logged in')); } return this.models.account.fetch(); }
  10. #3. Keep model-ish methods composable /** * Retrieve account data

    (if logged in) * * @return {Promise} */ fetchAccountData() { if (!this.session.isLoggedIn()) { return Promise.reject(new Error('not logged in')); } return this.models.account.fetch(); } Not chained
  11. #3. Every attached handler is async promise .then(doSomething) // nextTick

    .then(doSomethingElse) // nextTick .then(updateState) // nextTick .catch(onError); // nextTick
  12. #5. then(f, g) is not quite catch(g) Promise.resolve('foo') .then( function(v)

    { throw new Error('oops'); }, function(e) { /* I won't catch your error :-( */ } ); Promise.resolve('foo') .then(function(val) { throw new Error('oops'); }) .catch(function(e) { /* I will catch your error! :-D */ });
  13. #6. Adding library “promise support” is… tricky • Polyfill or

    leave to user? ◦ If polyfill, which implementation? ◦ How best to expose implementation?
  14. ES6-compatible Promise libraries • RSVP.js - superset of the ES6

    API ◦ es6-promise - subset of RSVP.js, implements ES6 API only • native-promise-only - ES6 polyfill • lie - tiny Promises/A+ implementation • Q.Promise - ES6 API implementation • es6-shim - full ES6 shim, includes Promise • core-js - lots of polyfills, including Promise. Used by babel-polyfill • polyfill.io - Polyfill service