I have a function like so:
let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
return function () {
if (!allow) return;
cb.call(ctx, ...arguments);
// cb.apply(ctx, arguments);
};
};
In case cb
is synchronous there is no problem, but how should I handle the case of cb
returns a promise (asynchronous)?
let cb = async ()=> {...};
let foo = maybeRun(cb, true);
await foo()
I want the returned function foo
to have same behaviour of cb
(sync or async).
CodePudding user response:
You don't have to do anything special at all; an async
function just returns a promise like any other return value.
But note that you're missing a return
in your wrapper function. Your function was throwing away any return value it got (including a promise).
let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
return function () {
if (!allow) return; // *** See note below
return cb.call(ctx, ...arguments);
// −−−−−^^^^^^
};
};
One wrinkle is that your wrapper now sometimes returns a promise and other times doesn't. There's nothing (standard) you can do to look at cb
(without calling it) to see whether it returns a promise, so that may just be a limitation you have to deal with. (You can sniff out whether it's an async
function, but you can't know if it's a non-async
function that returns a promise.)
In a comment, you've said:
i didn't write a return because the wrapped functions i need this function for have no returns
That changes things for your specific use case: You'd just use await
when calling the function:
let maybeRun = function (cb: Function, allow: boolean, ctx: object = window) {
return async function () {
// −−−−−−−−^^^^^
if (!allow) return;
await cb.call(ctx, ...arguments);
// −−−−−^^^^^
};
};
Now your function (being async
) always returns a promise, and in the cases where cb
returns a promise (either explicitly or because it's an async
function), your function will wait for that promise to settle before returning, but won't return the fulfillment value.
Note that even with that change, cb
is called synchronously when you call the wrapper function you got from maybeRun
. An async
function runs synchronously until the first time it has to wait for something. If cb
is synchronous, it'll be run during that initial synchronous execution of the wrapper.