Determine whether a method is synchronous or asynchronous

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.
}

I don't think there's a way you could programmatically know for certain, maybe with a heuristic you could get an estimate. Also It's possible a function could be both synchronous and 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.') });

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.

No, that's impossible. The methods aren't just marked synchronous or asynchronous, they either use callbacks or they don't.