Skip to content
Eoin Kelly edited this page May 9, 2014 · 5 revisions

this document is valid for version 1.2.0 of the Ember Inspector

Understand promises

Ember uses promises a lot and this tab will help you understand what is going on. If you are not sure what promises are these resources are good:

Understanding promises will make your time with Ember much more pleasant.

Labels

Ember uses the RSVP library to implement promises. It is fully compliant with the Promises/A+ specification and has a few nice extras. One of these is the ability to add a label to a promise that describes it. Creating a promise with a label looks like:

var promise = new Ember.RSVP.Promise(function (resolve, reject) {
  
  $.get( 'http://blah.com/api/important/stuff', 
    function (stuff) {
      resolve(stuff);
    },
    function (error) {
      reject(error);
    }
  );

}, 'Downloading the important stuff from blah.com');

var anotherPromise = promise.then(function (value) {
  // ...
},
function (error) {
  // ...
}, "Validating the stuff we got from blah.com")

Without the labels there would be no nice way for the inspector to identify the chunk of work that the promise handler performed - these promises will have the Then label in the inspector. Ember uses labels extensively in its internal promises and you should too.

Understanding the UI

The Promises tab has four columns:

  1. Label
    • The label attached to this chunk of work by the developer.
    • Trace is a clickable link that will dump a stack trace of ??? into the console
  2. State
    • The state that this promise is currently in. Values are one of Pending|Fulfilled|Rejected
      • Pending means that the callback for this promise has not run yet.
      • Fulfilled means that the promise resolved and the success callback function was run.
      • Rejected means the promise rejected and the _error callback function was run.
  3. Fullfillment/Rejection value
    • The value that the callback that was run (which depends on the state) returned.
      • If the state is fulfilled then this is the value of the success callback
      • Ff the state is Rejected then this is the return value of the error callback.
    • $E is a clickable link that will dump the value into the console for you to inspect
  4. Time to settle
    • How long did the callback take to complete.

Nested labels in the UI represents promises that are chained together by then(). For example if you see something like the following in the Label column:

Download a file from blah.com
  Validate JSON
    Create models from blah.com JSON

You can read it as Download the file from blah.com and then validate JSON and then create models from blah.com JSON

You can search promise labels and filter the promises shown by state using the toolbar at the bottom.

Learn by doing

The promises tab can be a little overwhelming at first because of how many promises Ember uses. Try this experiement to get a feel for how it works.

  1. Open the Ember Inspector on any Ember app (so Ember is loaded)
  2. Hit the 'clear' button on the bottom right of the Promises tab to remove promises generated by the app itself.
  3. Paste the code below into the console and watch how the promises inspector displays it.
  4. Tweak the code and re-run to improve your understanding

When you run this code notice the following:

  • How long does each chunk of work take to complete?
  • How is the dependency between p1 and p2 in this code displayed in the inspector?
// Ember.RSVP.Promise(resolverFunction, label)
var p1 = new Ember.RSVP.Promise(function(resolve, reject) {
  
  var val = "I am some vital data";

  // simulate a slow server  
  setTimeout(function () {
      resolve(val);
  }, 5000);

  // THIS WILL NEVER FAIL!
  // but if it did ...
  // var reason = new Error('The thing that should not be');
  //reject(reason);
  
}, "Pulling vital data from the Internets");

// .then(resolveCallback, rejectCallback, label)
var p2 = p1.then(
  function (p1val) {
    return p1val + " (has been validated)";
  },
  function (p1err) {
    // handle error from the operation that created p1
  },
  "Running spooky validations on it from a distance"
);

var p3 = p2.then(function (p2val) {
  return p2val + " (has been converted)";
}, null, "Converting it for use in our app")