-1

I need to know when all the work initiated by a function call is complete.

I have a function that takes another function as a parameter and calls on that function:

function outer(inner) {
   inner()
}

The inner function may initiate some async behavior:

function inner() {
   new Promise(...)
   new Promise(...)
   new Promise(...)
   requestAnimationFrame(...)
   requestAnimationFrame(...)
}

I know how Promise.all works. But for Promise.all, you need to pass an array of promises. I want my function to be unaware of the details of what happens inside the inner function. Since javascript handles a good deal of asynchronous behavior with callbacks instead of promises, Promise.all cannot handle every case of asynchronous work.

From the scope of the outer function, is there any way to detect whether the async and sync work of the inner function is complete, and for this behavior to apply to any function that I pass into outer?

function outer(inner) {
   inner.allWorkComplete(() => ...do more work)
   inner();
}

I am trying to avoid hardcoding this into the inner function, because that defeats the point of building a higher order function to handle the allWorkComplete event.

Is this simply an anti-pattern in javascript?

Jeremy Gottfried
  • 1,061
  • 13
  • 28
  • 2
    Possible duplicate of [How does promise.all work?](https://stackoverflow.com/questions/31299231/how-does-promise-all-work) – Steven Stark Mar 28 '19 at 21:28
  • No. Promise.all is completely different. – Jeremy Gottfried Mar 28 '19 at 21:28
  • How exactly is `Promise.all` different from `Promise.all` ? – Derek Pollard Mar 28 '19 at 21:29
  • @JeremyGottfried Your question is describing Promise.all, what is the issue with using that? – Steven Stark Mar 28 '19 at 21:33
  • The idea is that rather than simply pass an array of promises, I want to know when the work of the function is complete. The scope is different. For example, requestAnimationFrame is not technically a promise, but it is asynchronous. – Jeremy Gottfried Mar 28 '19 at 21:34
  • Do you know what promises are? – Kenneth K. Mar 28 '19 at 21:35
  • Yes, requestAnimationFrame is not a promise. It returns a number (not a promise), and calls a callback when the next frame is available. – Jeremy Gottfried Mar 28 '19 at 21:39
  • The "event" you are describing is exactly what the callback (for callback asynchonisity) and .then (in Promises) are. That is exactly what you are describing. – zero298 Mar 28 '19 at 21:42
  • I understand what a callback is. The idea here is to able to detect when work is done without explicitly knowing what the work is. Thanks to the answer below, I know that is impossible within the current standards.. – Jeremy Gottfried Mar 28 '19 at 21:54

1 Answers1

3

I want my function to be unaware of the details of what happens inside the inner function.

That's not possible[1].
The inner function needs to cooperate and tell you when it's finished - customarily, it does that by returning an appropriate promise.

1: Not without lots of effort, at least. You'd need to control the entire environment so that you can detect when any asynchronous primitive is called.

Is this simply an anti-pattern in javascript?

Yes. A function that does any asynchronous work either needs to handle the completion itself (if not interesting to anyone else), or provide a way to listen for it.

In your example, that means creating promises for the requestAnimationFrame calls, and then combining all the promises with Promise.all to return a promise that settles when your inner function finishes its tasks:

function inner() {
  return Promise.all([
    new Promise(...),
    new Promise(...),
    new Promise(...),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
    new Promise(resolve => {
      requestAnimationFrame(() => {
        ...
        resolve();
      })
    }),
  ]);
}

(Disclaimer: the above is not really good promise code - you shouldn't use new Promise too often, only in helper functions that wrap a particular asynchronous call but do nothing else - but should give you and idea of how promises can be used here)

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you for taking my question seriously and taking the time to answer it. I appreciate that. When I ask questions on this site, I feel like there's an assumption that I don't know what I'm talking about, when I'm actually just curious and unable to find an answer elsewhere. – Jeremy Gottfried Mar 28 '19 at 21:58