Want to see the full-length video right now for free?
 
  Promises are an abstraction that makes working with asynchronous code more manageable and consistent. Rather than passing a callback function to an asynchronous operation (and possibly falling into the dreaded callback pyramid of doom), the asynchronous operation can return a "Promise" representing the future value, or failure.
Here's an example in Node for finding the largest file in a directory (taken from strongloop):
var fs = require('fs')
var path = require('path')
module.exports = function (dir, cb) {
  fs.readdir(dir, function (er, files) {
    if (er) return cb(er)
    var counter = files.length
    var errored = false
    var stats = []
    files.forEach(function (file, index) {
      fs.stat(path.join(dir,file), function (er, stat) {
        if (errored) return
        if (er) {
          errored = true
          return cb(er)
        }
        stats[index] = stat
        if (--counter == 0) {
          var largest = stats
            .filter(function (stat) { return stat.isFile() })
            .reduce(function (prev, next) {
              if (prev.size > next.size) return prev
              return next
            })
          cb(null, files[stats.indexOf(largest)])
        }
      })
    })
  })
}
...and here's that same code, using the [Q promises library][q]:
[q]: http://documentup.com/kriskowal/q/
var fs = require('fs')
var path = require('path')
var Q = require('q')
var fs_readdir = Q.denodeify(fs.readdir)
var fs_stat = Q.denodeify(fs.stat)
module.exports = function (dir) {
  return fs_readdir(dir)
    .then(function (files) {
      var promises = files.map(function (file) {
        return fs_stat(path.join(dir,file))
      })
      return Q.all(promises).then(function (stats) {
        return [files, stats]
      })
    })
    .then(function (data) {
      var files = data[0]
      var stats = data[1]
      var largest = stats
        .filter(function (stat) { return stat.isFile() })
        .reduce(function (prev, next) {
        if (prev.size > next.size) return prev
          return next
        })
      return files[stats.indexOf(largest)]
    })
    .catch(console.log(error));
}
Let's go through all of that:
We're using
Q.denodeify
to create Q-compatible functions from Node functions. The then function takes
a function to execute once the promise is finished. We can chain .then (like
Q(function).then(...).then(...)) to run a bunch of promises one after each
other. The all function takes  an array of promises and wraps it in a promise
that resolves once all the promises have resolved.
The core idea of promises is that rather than passing a function that represents the next step (a "callback"), the promise inverts control and returns an object that represents the future state where we've resolved the asynchronous action and allows our code to maintain control over the flow of execution.
[The A+ spec][a+] is the specification for how promises must behave. Promises
start in the pending state and can move to resolved or rejected. The then
method takes two arguments, onFulfilled and onRejected. onFulfilled takes
the value of the successful computation, and onRejected takes the reason for
rejection. then can be called on the same promise multiple times and their
functions will run in the order they were called.
[a+]: https://promisesaplus.com/
This code creates a promise that waits 3 seconds then transitions to the
resolved state with the value 42:
// A Promise that returns a value
function theUltimateAnswer() {
  return new Promise(function(resolve) {
    setTimeout(function(){
      var value = 42;
      resolve(value);
    }, 3000);
  });
}
promise = theUltimateAnswer()
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
promise
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
promise
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: 42}
This code creates a promise that waits 3 seconds, then rejects:
// A Promise that just fails
function waitForIt() {
  return new Promise(function(resolve, reject) {
    setTimeout(function(){
      reject("Oh noes!");
    }, 3000);
  });
}
promise = waitForIt()
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
promise
// Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
// Uncaught (in promise) Oh noes!(anonymous function) @ VM194:6setTimeout
promise
// Promise {[[PromiseStatus]]: "rejected", [[PromiseValue]]: "Oh noes!"}
This code sample shows how to use the value from a successful promise:
function howDoIGetThatValue() {
  return new Promise(function(resolve) {
    setTimeout(function(){
      var value = 42;
      resolve(value);
    }, 1000);
  });
}
howDoIGetThatValue().then(function(result) {
  console.log(result);
});
This code sample shows how to handle a rejected promise:
// A Promise that just fails
function waitForIt() {
  return new Promise(function(resolve, reject) {
    setTimeout(function(){
      reject("Oh noes!");
    }, 1000);
  });
}
promiseWithThen = waitForIt().then(null, function(error){
  console.log(error);
});
promiseWithCatch = waitForIt().catch(function(error){
  console.log(error);
});
Errors will propagate along the chain:
// Where does it fail?
function waitForIt() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      if (Math.random() < 0.5) {
        reject("Oh noes!");
      } else {
        resolve("Everything is fine.");
      }
    }, 1000);
  });
}
waitForIt().then(function(result) {
  throw("Just kidding!");
}).catch(function(error) {
  console.log(error);
});
The following code is taken from [electron-boilerplate]:
[electron-boilerplate]: https://github.com/szwacz/electron-boilerplate/blob/4e1333bb2e79fd18476742e7f658a2519e5fa7bc/tasks/release_osx.js#L136-L147
module.exports = function () {
  return init()
    .then(copyRuntime)
    .then(cleanupRuntime)
    .then(packageBuiltApp)
    .then(finalize)
    .then(renameApp)
    .then(createInstaller)
    .then(cleanClutter)
    .catch(console.error);
};
request.then(function () {
  modalForm.form.removeClass('loading');
});
return this.get('favoritedItems').then(items => {
  return Ember.RSVP.Promise.all(
    items.mapBy('topics')
  ).then(topics => {
    return Ember.RSVP.Promise.all(
      topics.mapBy('items')
    );
  });
});
[Promises in Wicked Detail]: http://www.mattgreer.org/articles/promises-in-wicked-detail/ [Mozilla Developer Network Promise documentation]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise [Using JavaScript Promises to Reason About User Interaction]: https://robots.thoughtbot.com/using-javascript-promises-to-reason-about-user-interaction [You're Missing the Point of Promises]: https://blog.domenic.me/youre-missing-the-point-of-promises/ [Promise Anti-patterns]: http://taoofcode.net/promise-anti-patterns/