Skip to content

Promise.prototype.finally #18

@domenic

Description

@domenic
Owner

I am not sure why this wasn't in the original DOM spec, nor in @erights's concurrency strawman, but it's damn useful and not trivial to implement yourself.

Promise.prototype.finally = function (callback) {
    return this.then(
        value => this.constructor.resolve(callback()).then(() => value),
        reason => this.constructor.resolve(callback()).then(() => { throw reason; })
    );
};

Notably, like JS finally clause:

  • no value or reason is passed in to the finally code (i.e. to callback).
  • Does not affect the result, i.e. the resulting promise is still fulfilled with value or rejected with reason, just like the original one, unless...
  • If the finally code blows up (i.e. if callback throws, or returns a rejected promise), it propagates that failure onward, instead of the original success or failure.

Use cases collected so far:

  • Clean up event listeners, regardless of whether the promise succeeds or fails 1.
  • Hiding the spinner after a network request succeeds or fails 2.
  • Test teardown 3.

Activity

erights

erights commented on Sep 3, 2013

@erights
Collaborator

Absent from concurrency strawman, due only to oversight. I don't have experience with it. Sounds plausible. Can you point at some examples that illustrate well how it is useful?

domenic

domenic commented on Sep 3, 2013

@domenic
OwnerAuthor

Here is one quick example, where we use it to clean up event listeners: https://gist.github.com/domenic/6419679

erights

erights commented on Sep 3, 2013

@erights
Collaborator

Nice.
On Sep 3, 2013 5:33 AM, "Domenic Denicola" notifications@github.com wrote:

Here is one quick example, where we use it to clean up event listeners:
https://gist.github.com/domenic/6419679


Reply to this email directly or view it on GitHubhttps://github.com//issues/18#issuecomment-23708973
.

annevk

annevk commented on Sep 3, 2013

@annevk
Collaborator

If we think we can get consensus on this, seems fine, otherwise, please lets not add new features that will delay the whole thing longer.

domenic

domenic commented on Sep 3, 2013

@domenic
OwnerAuthor

Thanks for reining us in, @annevk :). My new position then is to default to not speccing it unless there's a sudden upswell of support due to your email this morning. We can always make it a high-priority addition later.

I'll close this in a day or so if said upswell does not appear.

mhofman

mhofman commented on Sep 3, 2013

@mhofman

I'd like to voice support for finally. I've had to implement it myself with the current version of DOM Promises and having it built-in would allow us to remove that piece of code which is basically there to restore a functionality that exists in synchronous operations.

domenic

domenic commented on Sep 4, 2013

@domenic
OwnerAuthor

Closing for now. I would like this a lot but getting something done is more important.

jakearchibald

jakearchibald commented on Nov 4, 2013

@jakearchibald

Another use-case for this is hiding a spinner after a network request succeeds or fails https://gist.github.com/jakearchibald/785f79b0dea5bfe0c448

kriskowal

kriskowal commented on Nov 4, 2013

@kriskowal

@jakearchibald Thanks. I often use finally for test teardown…

var HTTP = require("q-io/http");
var server = HTTP.Server(app);
return server.listen(0)
.then(function () {
    // run test
})
.finally(server.stop)
rauschma

rauschma commented on Oct 3, 2014

@rauschma

Minor correction: Promise.prototype.finally itself can’t be an arrow function – you are using this inside it.

stefanpenner

stefanpenner commented on Oct 3, 2014

@stefanpenner

@rauschma no it is correct, as it retains the this from the containing closure.

  // es3+ version
  'finally': function(callback) {
    var constructor = this.constructor;

    return this.then(function(value) {
      return constructor.resolve(callback()).then(function(){
        return value;
      });
    }, function(reason) {
      return constructor.resolve(callback()).then(function(){
        throw reason;
      });
    });
  }
stefanpenner

stefanpenner commented on Oct 3, 2014

@stefanpenner

oops i misread @rauschma you are correct!

domenic

domenic commented on Oct 3, 2014

@domenic
OwnerAuthor

Fixed the OP

21 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @stefanpenner@theefer@kriskowal@mhofman@jakearchibald

        Issue actions

          Promise.prototype.finally · Issue #18 · domenic/promises-unwrapping