Async & Promisesmedium

Implement Promise.prototype.finally

Implement a `finally` polyfill that runs a callback regardless of resolve/reject, while preserving the original outcome.

Asked at Apple, Stripe, Uber

#promises#polyfill#error handling

Answer

if (!Promise.prototype.myFinally) {
  Promise.prototype.myFinally = function (onFinally) {
    const P = this.constructor
    const handler =
      typeof onFinally === 'function' ? onFinally : () => undefined

    return this.then(
      (value) => P.resolve(handler()).then(() => value),
      (reason) =>
        P.resolve(handler()).then(() => {
          throw reason
        })
    )
  }
}

// Usage
Promise.resolve('ok')
  .myFinally(() => console.log('cleanup'))
  .then(console.log) // cleanup, ok

Promise.reject('err')
  .myFinally(() => console.log('cleanup'))
  .catch(console.error) // cleanup, err

Practise more Async & Promises questions →