How to know if a function is async?

后端 未结 8 794
别跟我提以往
别跟我提以往 2020-12-01 00:55

I have to pass a function to another function, and execute it as a callback. The problem is that sometimes this function is async, like:

async function() {
          


        
相关标签:
8条回答
  • 2020-12-01 01:34

    Hei,

    Here is an approach provided by David Walsh in his blogpost:

    const isAsync = myFunction.constructor.name === "AsyncFunction";
    

    Cheers!

    0 讨论(0)
  • 2020-12-01 01:35

    You can assume at begin that callback is promise:

    export async function runSyncOrAsync(callback: Function) {
    
      let promisOrValue = callback()
      if (promisOrValue instanceof Promise) {
        promisOrValue = Promise.resolve(promisOrValue)
      }
      return promisOrValue;
    }
    

    and them in your code you can do this:

    await runSyncOrAsync(callback)
    

    which will solve your problem with unknowing callback type....

    0 讨论(0)
  • 2020-12-01 01:37

    Both @rnd, and @estus are correct.

    But to answer the question with an actual working solution here you go

    function isAsync (func) {
        const string = func.toString().trim();
    
        return !!(
            // native
            string.match(/^async /) ||
            // babel (this may change, but hey...)
            string.match(/return _ref[^\.]*\.apply/)
            // insert your other dirty transpiler check
    
            // there are other more complex situations that maybe require you to check the return line for a *promise*
        );
    }
    

    This is a very valid question, and I'm upset that someone down voted him. The main usecase for this type of checking is for a library/framework/decorators.

    These are early days, and we shouldn't downvote VALID questions.

    0 讨论(0)
  • 2020-12-01 01:40

    I prefer this simple way:

    theFunc.constructor.name == 'AsyncFunction'
    
    0 讨论(0)
  • 2020-12-01 01:43

    In case you're using NodeJS 10.x or later

    Use the native util function.

       util.types.isAsyncFunction(function foo() {});  // Returns false
       util.types.isAsyncFunction(async function foo() {});  // Returns true
    

    Do keep all the concerns in mind from above ansers though. A function that just returns by accident a promise, will return a false negative.

    And on top of that (from the docs):

    Note that this only reports back what the JavaScript engine is seeing; in particular, the return value may not match the original source code if a transpilation tool was used.

    But if you use async in NodeJS 10 and no transiplation. This is a nice solution.

    0 讨论(0)
  • 2020-12-01 01:45

    It seems that await can be used for normal functions too. I'm not sure if it can be considered "good practice" but here it is:

    async function asyncFn() {
      // await for some async stuff
      return 'hello from asyncFn' 
    }
    
    function syncFn() {
      return 'hello from syncFn'
    }
    
    async function run() {
      console.log(await asyncFn()) // 'hello from asyncFn'
      console.log(await syncFn()) // 'hello from syncFn'
    }
    
    run()
    
    0 讨论(0)
提交回复
热议问题