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() {
Hei,
Here is an approach provided by David Walsh in his blogpost:
const isAsync = myFunction.constructor.name === "AsyncFunction";
Cheers!
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....
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.
I prefer this simple way:
theFunc.constructor.name == 'AsyncFunction'
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.
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()