8

I have a function which returns a Promise.

Now, sometimes it makes sense for the consumer to use the "then" function on that Promise. But sometimes the consumer simply does not care about when the Promise resolves, and also not about the result - in other words the same function should also be able to be called in a "fire and forget" manner.

So I want these two usage scenarios:

func().then( ... ); // process Promise
func(); // "fire and forget"

This apparently works, but I wonder if this is considered "bad practice", and in particular if this usage pattern could have any unwanted side effects, ie. leading to memory leaks? Right now I am using bluebird, but I consider to switch to native Promises if that makes any difference.

frontend_dev
  • 1,693
  • 14
  • 28
  • +1, though I dont think it would cause any issue. but as you've asked about memory leak.. I am curious to know :) – Aman Gupta Sep 19 '15 at 16:10
  • 1
    possible duplicate of [Can I fire and forget a promise in nodejs (ES7)?](http://stackoverflow.com/q/32384449/1048572) (which uses the `async`/`await` syntax, but the premise is the same) – Bergi Sep 19 '15 at 16:21
  • Yes, Bergi sounds at least similar - sorry I did not find this when searching for an answer. Only difference is that I am not using node though. – frontend_dev Sep 19 '15 at 16:23

1 Answers1

6

Remember that every call to then results in a new promise. So any Promise implementation that had a memory leak as a result of a promise not having any resolution handlers attached would be a broken implementation, what with all those promises that we never hook handlers to being returned. I very much doubt implementations of ES2015's promises, Bluebird, Q, etc. have that behavior.

Separately, as conceptually a promise's resolution handlers are basically just functions stored by the promise and then called when appropriate, it's not likely to be a memory leak if you never give it any functions to store.

But, there is a problem with your fire-and-forget, just not a memory leak problem: It breaks one of the main Promise rules: Either handle rejection, or return the promise chain to something else that will handle rejection. Since you're not doing that, if the operation fails, you'll have an unhandled rejection. Unhandled rejections are reported to the console and in some environments may terminate your app (at some point, Node.js may start terminating the process when this happens, see this open issue).

If the fact that then returns a new promise is a surprise, consider:

let p1 = new Promise(resolve => {
  setTimeout(() => {
    resolve('a');
  }, 100);
});
let p2 = p1.then(result => {
  console.log("p1.then got " + result);
  return 'b';
});
p2.then(result => {
  console.log("p2.then got " + result);
});

which outputs

p1.then got a
p2.then got b
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    I didn't address the "bad practice" part as that's probably subjective. But I'll note that it's really common to not use the return value of a function, which arguably is the non-promise equivalent of not adding any handlers to the promise. – T.J. Crowder Sep 19 '15 at 16:20
  • @T.J.Crowder - so what is your answer to OP "will this cause any issues/unintended side effects or memory leaks"? Sounds like your answer to OP is "No", or...? – Don Cheadle May 22 '19 at 14:07
  • @DonCheadle - I think I covered that in my opening paragraph. No, it won't cause memory leaks. :-) – T.J. Crowder May 22 '19 at 14:15