判断异步函数需依据语言原生特性:python用inspect.iscoroutinefunction()检测async def定义的协程函数;js用object.prototype.tostring.call(func)===“[object asyncfunction]”识别asyncfunction类型,行为异步不等于函数异步。

判断一个函数是否为异步函数,关键看它是否在语言层面具备“原生异步”特性,而不是仅看行为是否“非阻塞”。不同语言有不同判断依据,不能一概而论。
Python:看定义方式和类型标识
Python 中,真正的异步函数必须用 async def 定义,返回协程对象(coroutine),不是普通函数或线程包装的“伪异步”。
- 用 inspect.iscoroutinefunction() 最可靠:它返回
True仅当函数是async def定义的原生协程函数 -
asyncio.iscoroutinefunction() 在 Python 3.8+ 与前者等价,也可用;对被
functools.partial或某些装饰器包裹的异步函数兼容性略好 - 仅靠“调用后不阻塞”或“开了线程”不能说明它是异步函数——比如用
threading.Thread包装的async_call是并发,不是协程异步 - 函数体里有没有
await不是判断依据(可能写但没声明async,会报语法错误);关键是函数定义开头是否有async关键字
JavaScript:靠构造器或类型标签识别
JS 中 async 函数是独立的内置类型,普通函数即使返回 Promise,也不等于它是 async 函数。
- 推荐用
Object.prototype.toString.call(func) === '[object AsyncFunction]':安全、无需执行函数、全环境兼容(包括浏览器) - 检查
func.constructor.name === 'AsyncFunction':简洁有效,但需确保func非 null/undefined - 避免用
typeof func === 'function':两者都返回'function',无法区分 - 避免仅靠
func() instanceof Promise:普通函数也能手动返回 Promise,这不是 async 函数的充分条件
别被“行为”误导:异步调用 ≠ 异步函数
很多场景下,函数看起来“能异步执行”,但本质不是异步函数:
- Python 里用多线程/多进程跑的普通函数(如装饰器实现的
async_call)只是并发,不是协程异步 - JS 里用
setTimeout或Promise.resolve().then()包裹的普通函数,仍是同步函数,只是延迟执行 - 返回 Promise 的函数不一定是 async 函数——
function f() { return Promise.resolve(1); }是同步函数
实际验证小技巧
写个快速检测工具,比查文档更快:
- Python:
import inspect; print(inspect.iscoroutinefunction(your_func)) - JS:
const isAsync = f => Object.prototype.toString.call(f) === '[object AsyncFunction]'; console.log(isAsync(yourFunc)); - 运行前先确认函数变量确实存在且是函数类型,避免
TypeError - 测试时注意环境一致性——比如某些 JS 工具函数在 uni-app 或旧版 WebView 中可能受限











