Proposal: Promise.prototype.Finally

# Ron Buckton (5 years ago)

I created the following gist as a proposal for the addition of a finally method to the prototype of the Promise constructor, either for ES6 (if such a thing is considered valuable and could be fast tracked at this date), or for ES7. This method would take in a single callback that would be executed once when the antecedent Promise is settled regardless of whether it was fulfilled or rejected. If the callback results in a normal completion, the state of the antecedent promise would be adopted by the new Promise. However, if the callback results in an abrupt completion, the new Promise would be rejected with this reason.

You can find more details about this proposal along with amendments to the current ES6 working draft at gist.github.com/rbuckton/66918c8491aa335b003c

After working heavily with an ES6 Promise shim as of late, I have found such a feature would be very valuable. It is possible to patch the ES6 Promise API to add such a feature, however it seems like it could be a worthwhile addition that could benefit the community until such a time as an async/await-like syntax is available in ES7+.

# Domenic Denicola (5 years ago)

Here is the current design for Promise.prototype.finally. I agree it is a useful feature.

domenic/promises-unwrapping#18

# David Bruant (5 years ago)

Yes. Needed it recently. Ended up doing ".then(f).catch(f)" which can be survived but feels stupid.

# Tab Atkins Jr. (5 years ago)

And doesn't have the correct pass-through behavior, unless you've got a switch in "f" that makes it return or throw based on whether the argument is an Exception.

# Ron Buckton (5 years ago)

I like the addition that your version of finally can itself return a Promise, which I hadn't considered (as I hadn't had a need for it myself yet). Is the consensus that this won't make it into Promise until at least ES7, and then only if there's enough of a call for it?

To be honest, if ES7 has something like async/await then it won't need Promise.prototype.finally. Promise.prototype.finally is primarily a feature needed for Promises without async/await (e.g. in the ES6 timeframe, or ES7 if async/await is deferred to a later revision).

# Domenic Denicola (5 years ago)

Is the consensus that this won't make it into Promise until at least ES7, and then only if there's enough of a call for it?

Although I find the arbitrary division of features into "ES6" and "ES7" distasteful personally: yes, ES6 will not be adding new APIs. That doesn't mean that Promise.prototype.finally won't ship in all major browsers before other ES6 features do. But it does mean that we won't be submitting a document to the Ecma general assembly with Promise.prototype.finally before we submit one with proper tail calls.

To be honest, if ES7 has something like async/await then it won't need Promise.prototype.finally.

That's mostly true, I suppose, but it can increase brevity in some cases:

function doThingySafely() {
  return doThingy().finally(cleanup);
}

// vs.

async function doThingySafely() {
  try {
    return await doThingy();
  } finally {
    return cleanup();
  }
}