如何知道一个函数是否异步? [英] How to know if a function is async?

查看:617
本文介绍了如何知道一个函数是否异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须将一个函数传递给另一个函数,并将其作为回调执行.问题是有时此函数是异步的,例如:

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() {
 // Some async actions
}

所以我要根据接收的函数类型执行await callback()callback().

So I want to execute await callback() or callback() depending on the type of function that it is receiving.

有没有办法知道函数的类型?

Is there a way to know the type of the function??

推荐答案

本机async函数可能是可识别的

Native async functions may be identifiable when being converted to strings:

asyncFn[Symbol.toStringTag] === 'AsyncFunction'

或通过 AsyncFunction 构造函数:

Or by AsyncFunction constructor:

const AsyncFunction = (async () => {}).constructor;

asyncFn instanceof AsyncFunction === true

这不适用于Babel/TypeScript输出,因为asyncFn是已编译代码中的常规函数​​,它是FunctionGeneratorFunction的实例,而不是AsyncFunction.为确保不会在编译后的代码中为生成器和常规函数提供误报:

This won't work with Babel/TypeScript output, because asyncFn is regular function in transpiled code, it is an instance of Function or GeneratorFunction, not AsyncFunction. To make sure that it won't give false positives for generator and regular functions in transpiled code:

const AsyncFunction = (async () => {}).constructor;
const GeneratorFunction = (function* () => {}).constructor;

(asyncFn instanceof AsyncFunction && AsyncFunction !== Function && AsyncFunction !== GeneratorFunction) === true

由于本机async函数于2017年正式引入Node.js,因此该问题可能涉及async函数的Babel实现,该实现依赖于

Since native async functions were officially introduced to Node.js in 2017, the question likely refers to Babel implementation of async function, which relies on transform-async-to-generator to transpile async to generator functions, may also use transform-regenerator to transpile generator to regular functions.

async函数调用的结果是一个承诺. 根据该提案,承诺或不承诺可能是传递给await,因此await callback()是通用的.

The result of async function call is a promise. According to the proposal, a promise or a non-promise may be passed to await, so await callback() is universal.

只有少数情况可能需要这样做.例如,本机async函数在内部使用本机承诺,并且如果更改了其实现,则不会选择全局Promise:

There are only few edge cases when this may be needed. For instance, native async functions use native promises internally and don't pick up global Promise if its implementation was changed:

let NativePromise = Promise;
Promise = CustomPromiseImplementation;

Promise.resolve() instanceof Promise === true
(async () => {})() instanceof Promise === false;
(async () => {})() instanceof NativePromise === true;

这可能会影响函数的行为(这是 Angular和Zone.js承诺实现的已知问题).即使那样,最好还是检测出不希望有函数返回值的Promise实例,而不是检测出函数是async的原因,因为相同的问题适用于使用替代promise实现的任何函数,而不仅仅是async(解决方案所说的Angular问题是用Promise.resolve包装async返回值).

This may affect function behaviour (this is a known problem for Angular and Zone.js promise implementation). Even then it's preferable to detect that function return value is not expected Promise instance instead of detecting that a function is async, because the same problem is applicable to any function that uses alternative promise implementation, not just async (the solution to said Angular problem is to wrap async return value with Promise.resolve).

TL; DR:async函数不应与返回promise的常规函数​​区分开.没有可靠的方法,也没有理由检测非本机编译的async函数.

TL;DR: async functions shouldn't be distinguished from regular functions that return promises. There is no reliable way and no reason to detect non-native transpiled async functions.

在ES6中,这是通过Promise.resolvePromise构造函数完成的(还处理同步错误):

In ES6, this is done with Promise.resolve or Promise constructor (also handles synchronous errors):

Promise.resolve(fnThatPossiblyReturnsAPromise())
.then(result => ...);

new Promise(resolve => resolve(fnThatPossiblyReturnsAPromiseOrThrows()))
.then(result => ...);

在ES2017中,这是通过await完成的:

In ES2017, this is done with await:

let result = await fnThatPossiblyReturnsAPromiseOrThrows();
...

这篇关于如何知道一个函数是否异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆