6

I have an asynchronous function that returns a promise. The operation should only be performed once. I want all callers of that function to get back the same Promise, but I don't want .catch()es of one caller to affect another caller. Can I clone a promise, or implement this in another way?

apscience
  • 7,033
  • 11
  • 55
  • 89
  • Possible duplicate of [Memoization of promise-based function](http://stackoverflow.com/q/28763057/1048572)? – Bergi May 06 '16 at 02:37

1 Answers1

8

but I don't want .catch()es of one caller to affect another caller.

They never1 do (unless you've chained the callbacks, which you don't).

I want all callers of that function to get back the same Promise

Just do it. Promises are immutable values2.

Can I clone a promise?

If you really need3 a distinct object that will follow the original promise (fulfill when it fulfills or reject when it rejects), you can use the then method without arguments:

var clone = promise.then();
console.assert(clone !== promise);

1: Assuming you use a proper promise library. I think I can remember a case of a library (old jQuery?) where then callback results changed the state of the promise.
2: In their resolving behaviour, at least. Every promise is still just an object of course.
3: You don't. You really should not. I'm just answering the title question, but you should stop doing weird stuff.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Why would you ever need a distinct object that follows the first one? Why not just have multiple pieces of code all use the same promise if you want multiple followers of the same resolve/reject? – jfriend00 May 06 '16 at 02:57
  • 1
    @jfriend00: I don't know, people are doing weird stuff with promises, and I was thinking of custom properties on the *object* that you don't want to share. Also handing out multiple different promise instance might make a difference for cancellation (depending on the implementation semantics). But yes, under usual circumstances you should just reuse the exact same promise. Do I need to make this more clear in the answer? – Bergi May 06 '16 at 03:00
  • I think you should probably make it more clear that 99% of the time (basically always unless you're doing something non-standard to the promise object itself), you don't need another promise and all pieces of code can just watch the same promise. – jfriend00 May 06 '16 at 03:16
  • One use-case I can think of is a "deep clone" utility that tries to be amicable to consuming code i.e. it assumes the promise is mutable and thus makes a best attempt at cloning it. – aaaaaa Apr 13 '18 at 19:44
  • 1
    @aaaaaa Yes, but promises really shouldn't have mutable custom properties in general. But when you don't trust your consumers not to install them, handing out multiple "copies" of the same promise can indeed be useful. – Bergi Apr 14 '18 at 09:07
  • @Bergi This answer has an use case. Time outing a promise. – jeffbRTC Apr 01 '21 at 00:48
  • @jeffbRTC Not sure I follow. A time-outed promise (like [this](https://stackoverflow.com/a/37120577/1048572)?) has a different behaviour than the original one, it's not a clone. – Bergi Apr 01 '21 at 10:14
  • @Bergi See last code snippet of this answer, https://stackoverflow.com/a/66895543/14659574 – jeffbRTC Apr 01 '21 at 13:14