Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine whether a method is synchronous or asynchronous

Tags:

In node.js, is it possible to determine (using a function) whether a method is synchronous or asynchronous?

I'd like to write a function that does the following:

function isSynchonous(methodName) {
    //if the method is synchronous, return true. Otherwise, return false.
}
like image 315
Anderson Green Avatar asked Oct 01 '12 20:10

Anderson Green


People also ask

How do you know if a code is synchronous or asynchronous?

The differences between asynchronous and synchronous include: Async is multi-thread, which means operations or programs can run in parallel. Sync is single-thread, so only one operation or program will run at a time. Async is non-blocking, which means it will send multiple requests to a server.

What is the difference between synchronous and asynchronous?

The key difference between synchronous and asynchronous communication is synchronous communications are scheduled, real-time interactions by phone, video, or in-person. Asynchronous communication happens on your own time and doesn't need scheduling.

What is asynchronous vs synchronous programming?

While asynchronous operations can run multiple tasks concurrently on a single thread, synchronous programs have a task queue where every other task remains idle while the first is completed. By definition, synchronous means 'connected' or 'dependent'.

How do you know if a code is asynchronous?

To check if a function is async, access the constructor.name property on the function and check if the value is equal to AsyncFunction , e.g. myFunction.constructor.name === 'AsyncFunction' . If the equality check returns true , then the function is async.


2 Answers

From a language standpoint this is not possible, which I believe llambda's answer proves.

  • Functions can do things asynchronously but return something synchronously; say, return the number of async tasks that were fired off.
  • Functions can synchronously return promises... that represent asynchronous information. I would call such a method asynchronous but the language can't really tell that.
  • In some perverse sense every asynchronous function "returns" something... undefined if nothing else.

From an engineering standpoint:

  • read the documentation.
  • If the function accepts a callback, it is likely asynchronous. Look at the function signature.
  • Read the code.
  • Use "common sense." If the function does IO and returns a result from IO it must be, in some case, asynchronous. This includes file reading, reading from standard input, saving to a database, and HTTP/AJAX requests. Note streams are often used for this, which represents an asynchronous task, but the callbacks are special.

Furthermore there are functions that mix the two.

function(callback) {
    if(ready) {
        callback();
    }
    else {
        setTimeout(callback, 5000);
    }
}

Arguably this is very evil, and correct practice would be

if(ready) {
    process.nextTick(callback);
}

so the function has uniform behavior.

However there is a hacky way to tell if anything asynchronous happened, at least in Node.js. See this discussion.

// untested!! please read the documentation on these functions before using yourself
var work = process._getActiveHandles().length + process._getActiveCallbacks().length;
foo;
var newWork = (process._getActiveHandles().length + process._getActiveCallbacks().length) - work;
if(newWork > 0) {
    console.log("asynchronous work took place.");
}

This works because asynchronous work cannot resolve on the same tick, by definition, and because Node.js is single threaded.

like image 57
djechlin Avatar answered Oct 02 '22 13:10

djechlin


You don't necessarily know. A function could even be randomly synchronous or asynchronous.

For example, a function that takes another function could execute that function immediately, or it could schedule to execute it at a later time using setImmediate or nextTick. The function could even randomly choose to call its passed function synchronously or asynchronous, such as:

console.log('Start')

function maybeSynchOrAsync(fun) {

  var rand = Math.floor((Math.random() * 2))

  if (rand == 0) {
    console.log('Executing passed function synchronously')
    fun()
    console.log('Done.')
  } else {
    console.log('Executing passed function asynchronously via setImmediate')
    setImmediate(fun)
    console.log('Done.')
  }
}

maybeSynchOrAsync(function () { console.log('The passed function has executed.') });

Further, technically speaking, every function call is synchronous. If you call a function F, and F queues a callback function to be invoked later (using setTimeout or whatever mechanism), the original function F still has a synchronous return value (whether it's undefined, a promise, a thunk, or whatever).

like image 26
lammy Avatar answered Oct 02 '22 12:10

lammy