Determine whether a method is synchronous or asynchronous

前端 未结 3 823
暖寄归人
暖寄归人 2021-02-07 06:13

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:

<
相关标签:
3条回答
  • 2021-02-07 06:38

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

    0 讨论(0)
  • 2021-02-07 06:42

    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.

    0 讨论(0)
  • 2021-02-07 06:53

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

    0 讨论(0)
提交回复
热议问题