1

Say someone implemented a different setTimeout function:

const setTimeout = (func, ms) => {
  const future = Date.now() + ms;
  while (Date.now() < future) {
    // do nothing
  }
  func();
};

Which (for the simplicity of this question) has almost the same interface as the original one. How can I, as a developer using it, can verify it did not initialize any async code?

I want to know if my program will exist after I use the setTimeout call. If the setTimeout is implemented using sync code, the program will exist (shortly) after. If the implemenation of setTimeout is async, the program will exist only after the async code is done.

More specifically, can I do something like that?

setTimeout(()=>{},1000);
const isAnyAsyncCodeWillRun = ...;
if(isAnyAsyncCodeWillRun){
   console.log('Program wont exist right now, only in about 1000ms');
} else {
   console.log('Program will exist now');
}
YardenST
  • 4,829
  • 2
  • 31
  • 47
  • Other than checking if the return value is a [thenable](https://promisesaplus.com/) object, there's not much you can do. Any function can make asynchronous calls without providing hooks for the caller to register, even if the function blocks for a long time. – Patrick Roberts Feb 05 '19 at 18:06
  • What do you think your `setTimeout2` does? Because I'm almost positive that it will lock the execution context until the `while` gets satisfied. By that, I mean nothing else will execute. – zero298 Feb 05 '19 at 18:07
  • 1
    Your "better" setTimeout function is just a busy loop that blocks any code from executing. If you want to be able to detect when asynchronous code is queued into the event loop you can utilize the [async_hooks](https://nodejs.org/api/async_hooks.html) module. – Jake Holzinger Feb 05 '19 at 18:08
  • What is the actual problem that you are trying to solve? – guest271314 Feb 05 '19 at 18:10
  • 1
    I’m aware of the nature of my setTimeout2 and the reason I’ve implemeted it like this was intented. @Jake thanks I’ll check that – YardenST Feb 05 '19 at 18:11
  • 1
    Possible duplicate of [How to know if a function is async?](https://stackoverflow.com/questions/38508420/how-to-know-if-a-function-is-async) – fnune Feb 05 '19 at 18:13
  • 1
    If you're ok with using Node to verify, you can use `process._getActiveHandles()` and `process._getActiveRequests()` to inspect what is in the event loop, and if anything is added, (and nothing else was running asynchronously as the time) you can assume that *something* asynchronous is running. – dave Feb 05 '19 at 18:16
  • 1
    @FaustoNA it is not a duplicate. What you linked here is a special case of async function, therefore we are talking about promises, which is one implementation of handling async code. Thanks – YardenST Feb 05 '19 at 19:57
  • @guest271314 The problem is written in my 2nd example code which is: fill out line 2 (the ... part) so the following lines will work as expected. Thanks – YardenST Feb 05 '19 at 19:58
  • Thanks for the comments all. Ive edited the question to make it more specific and less abstract. Would appreciate new comments/answers – YardenST Feb 05 '19 at 20:04
  • @dave it seems that not all async code update these counters (the immediate for example) any suggestions? – YardenST Feb 08 '19 at 06:50
  • @JakeHolzinger since these hooks are also async, I was not able to use them to solve it (I've tried to generalize Bergi answer with your method). But anyhow - really nice feature - I was not aware of it. Thanks! – YardenST Feb 08 '19 at 06:51

1 Answers1

2

Yes, the term "asynchronous" means that the function returns before it is finished doing its work, and when supplied a callback will call that later. So you can use

let done = false;
let returned = false;
unknownFunction(() => {
    done = true;
    if (returned) console.log("callback is getting called asynchronously");
});
returned = true;
if (done) console.log("callback was called synchronously");

Of course, you cannot synchronously determine whether the function will later do something asynchronously (unless your environment provides special hooks for this).

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
  • Thanks this is helpful, and it seems you understand my concerns. Given that the environment is nodejs, are there any hooks I can use to determine it synchronously? – YardenST Feb 05 '19 at 19:56
  • 1
    Dave and Jake mentioned some in the comments, but I don't know the details – Bergi Feb 05 '19 at 20:01