Should I use resolve & reject in a yes-or-no scenario

# Gray Zhang (10 years ago)

Recently I was reviewing my code repository and the useless of Promise, I found we have majorly 2 scenario to use Promise:

Just match the synchronous flow control, so then matches return and catch matches catch Use it for a yes-or-no scenario, this is what I’m confusing For the 2nd scenario, a best example should be a confirm dialog, which returns a Promise which resolves after user click the “YES” button and rejects after the “NO” button is clicked, so the usecase could be:

var confirming = wairForUserConfirm('Continue to exit?'); confirming.then(exitApplication);

I see it a “reasonable” scenario, in this case the resolve means user resolves your question and reject means user rejects, seems a good story up to now

The problem is, in such case we usually do not attach a catch to rejections, once the global uncaught exception handling for promise is done, it may throw a window.onerror message which is not expected

Therefore, I’d like to ask whether we should ONLY use Promise as a return-or-throw synonyms, or we should use it in a yes-or-no scenario

# Frankie Bagnardi (10 years ago)

There's no real good answer here. From a practical standpoint, I'd say the because the code paths for 'the user said yes' and 'the user said no', are often completely exclusive, you should reject on a no response, and just use a dummy rejection handler when the code paths would converge (or at the end of the chain if that never happens).

Note: there's nothing wrong with not handling a rejection, and the dummy rejection handler is a solution to a problem of the solution to silent failures. By doing this, you're reinstating the problem of silent failures, even when caused by the programmer (see code below).

The second solution is to encode the answer in the resolution, and only reject if e.g. the question is unable to be asked (because it comes from a server endpoint which gives a 503, or whatever). This option mostly makes sense if you're done with promises, check the resolution value, and branch out into code that doesn't need to report its status back. Show an error message if the promise was rejected. You can do the same by pattern matching on the rejection reason (example in bluebird):

wairForUserConfirm('Continue to exit?') .catch(ServerError, (e) => {showErrorToUser(e); throw e}) .then(exitApplication) .catch(Modal.Cancel, noop) // handle this 'Error', but not e.g. ReferenceError, TypeError

As with anything: consider 'which will make my code easier to read and maintain', make an educated guess, and do it!

# Domenic Denicola (10 years ago)

From: es-discuss [mailto:es-discuss-bounces at mozilla.org] On Behalf Of Gray Zhang

Therefore, I’d like to ask whether we should ONLY use Promise as a return-or-throw synonyms, or we should use it in a yes-or-no scenario

You should only use the rejection channel of promises for exceptional situations, similar to what you would use synchronous exceptions for.

www.w3.org/2001/tag/doc/promises-guide#rejections

# Salvador de la Puente González (10 years ago)

From my point of view, rejection is the way to communicate "out-of-domain" values. So, in your scenario, the domain of answers has two values "accept" and "reject" or "deny" (to avoid confusion) so you should handle these two answers in the resolved handler.

# Gray Zhang (10 years ago)

Now I have to change my confirm method to match the “reject only for exception” rule, for some backward compatibility reason, I’d like to have a promise which “resolves when user answers OK and do nothing when user says NO”, it may cause a promise never be fulfilled (either resolve or reject), is there any potential side effect to create a never-fulfilled promise?

# Domenic Denicola (10 years ago)

No. In this respect it's like an event that never fires.

# Salvador de la Puente González (10 years ago)

Nop if you're aware of it. It could incur in memory leaks caused by the objects being held by the handlers or the handler itself.