An ‘always’ function for Ember.js Promises

Update (11th June 2014) As was pointed out by @EmberSherpa, there’s the finally method that does exactly this. So just don’t read this blog post and use that instead!

In the Hstry application, I had the situation where I needed to perform some operations, regardless of the result of a Promise. Unfortunately, the Promises/A+ spec does not specify an always function so this behavior was not implemented in the RSVP implementation that Ember.js uses.

On GitHub, Yehuda Katz suggests extending RSVP with the following method andThen:

/* 'andThen' is like 'then', but it takes a third
/* parameter `always` that is always executed,
/* no matter what the outcome of the Promise. */
Ember.RSVP.Promise.prototype.andThen = function(success, error, always) {
  return this.then(function(value) {
    var ret = success(value);
    always(value);
    return ret;
  }, function(reason) {
    var ret = error(reason);
    always(reason);
    return ret;
  });
};

Unfortunately, this doesn’t work for promises returned by DS.Model.save() in Ember Data because they are not of the type Ember.RSVP.Promise but instead implement the Ember.PromiseProxyMixin mixin (anyone can clarify me on why that is?). To solve this, we add the following:

// See http://stackoverflow.com/a/24164813/1269194
Ember.PromiseProxyMixin.reopen({
  andThen: function() {
    var promise = this.get('promise');
    return promise['andThen'].apply(promise, arguments);
  }
});
Write us your thoughts about this post. Be kind & Play nice.