Determine whether a method is synchronous or asynchronous

前端 未结 3 871
暖寄归人
暖寄归人 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条回答
  •  萌比男神i
    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.

提交回复
热议问题