Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tapReflect() / observe state in finally() #1639

Open
cdhowie opened this issue Mar 5, 2020 · 0 comments
Open

tapReflect() / observe state in finally() #1639

cdhowie opened this issue Mar 5, 2020 · 0 comments

Comments

@cdhowie
Copy link

cdhowie commented Mar 5, 2020

I have a use case where I always want to do something when a promise is settled, but with minor differences depending on whether the promise was fulfilled or rejected. However, I don't want to change the fate of the returned promise.

What I'm looking for is a combination of .finally() and .reflect(), where my handler is always called and can observe the state of the promise, but returning a promise with the same eventual state as the promise I invoke on (unless my handler returns a rejected promise, as usual).

My use case is sending a "task completed" notification to a message queue, regardless of whether the task succeeded or failed, but with contents indicating success or failure. However, the returned promise should remain fulfilled or rejected so the caller can naturally proceed depending on the result (without requiring the caller to understand the PromiseInspection object).

There's a few workarounds for this:

function theHandler(err, value) {
  // do some stuff
}

// Elsewhere
return somePromiseChain()
.tapCatch(theHandler)
.tap(value => theHandler(null, value));

Declaring the function out-of-band is a bit of an awkward maneuver to accomplish this.

Another option:

return somePromiseChain()
.reflect()
.then(pi => {
  // do some stuff

  return pi.isRejected() ? Promise.reject(pi.reason()) : Promise.resolve(pi.value());
})

This is a bit verbose... a wrapper function converting a PromiseInspection back into a Promise would help, but still feels like a hack.

I'm using this currently:

Promise.prototype.tapReflect = function (handler) {
  return this
  .reflect()
  .then(handler)
  .return(this);
};

It seems like this might be useful to others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant