判断Javascript函数是否是Async函数有好几种办法:
- 调用
Object.prototype.toString.call(async function(){})
,如果返回[object AsyncFunction]
,则阐明是Async函数。 简略地调用
asyncFn.toString()
async function myAsyncFunc(){}myAsyncFunc.toString() // 后果="async function myAsyncFunc(){}"
asyncFn.toString()
间接返回函数定义字符,只有判断是否以async结尾
即可。
以上算是比拟规范的办法,在原生反对ES6/7/8以下的浏览器中是没有问题的,然而在启用了Babel转码
后就有效
了。比方在Babel7
中, async function myAsyncFunc(){}
会被转码成:
function myAsyncFunc() { .... return _regenerator.default.async(function myAsyncFunc$(_context) { ..... }}
因而,如果还是用上述办法就有效了。因为被Babel转码后,所有的async均被转成一般的函数。
例如在React Native
环境就启用了Babel转码,调用Object.prototype.toString.call(async function(){})
,如果返回的是[Object Function]
。
因为在很多场景下咱们会启用Babel
转码.因而,判断是否是Async
函数,须要思考此状况。
根本办法就是通过asyncFunc.toString()
获取到函数内容,判断Babel
转码后的async
函数特色即可。
export function isAsyncFunction(fn){ let fnStr =fn.toString() return Object.prototype.toString.call(fn) === '[object AsyncFunction]' || fnStr.includes("return _regenerator.default.async(function")}
须要留神的是,async函数经Babel 5/6/7
经转码后生成的代码,在不同的版本下可能是不一样的,甚至也不排除将来Babel 8
转码的后果也会发生变化。因而,此办法并不一定牢靠,有谁晓得更加规范通用的办法能够告知一下。
因为Babel转码的状况存在,因而像判断一个对象是否是Class的函数,也存在相似因Babel转码导致的问题。例如:
function isClass(obj){ if (typeof(cls) === 'function' && cls.prototype) { try { cls.arguments && cls.caller; } catch(e) { return true; } } return false;}
以上函数在经Babel转码的状况下是有效的,如果适应Babel转码的状况,也一样要进行解决。