Sometimes you want your synchronous function to run asynchronously. Perhaps you want to run multiple functions asynchronously using something like Promise.allSettled
or Promise.all
.
I have a number of setup functions that dont depend on each other in an application and I was curious how hard it would be to convert the setup functions to async functions without touching their internal code. (Some functions come from libraries)
The TLDR is that yes, I managed to do it.
function asPromise (callback, ...args) {
return new Promise((resolve, reject) => {
try {
resolve(callback(...args))
} catch(e) {
reject(e)
}
})
}
Now for some examples:
function greet (greeting, name) { return "${greeting}, {name}" }
await asPromise(greet, "hi", "konnor")
// => "hi, konnor"
Now what if we pass an object?
function greet ({greeting, name}) { return "${greeting}, {name}" }
await asPromise(greet, {greeting: "hi", name: "konnor"})
// => "hi, konnor"
And finally, what about an array?
function greet (ary) {
return `${ary[0]}, ${ary[1]}`
}
await asPromise(greet, ["hi", "konnor"])
// => "hi, konnor"
Are there edge cases? Probably. Mostly around this
if your function calls rely on this
make sure to bind within the Promise like so:
await asPromise(myFunction.bind(myThis), "arg1")
And that's all for today! Short and sweet.
Top comments (2)
Hey, Konnor! An interesting take on making a Promise wrapper around otherwise synchronous functions.
I may suggest preserving the original function's (
callback
) call signature.This way your
asPromise
function doesn't have to forward arguments and care about the correct binding of thecallback
. It becomes focused on the one thing it was written to do: taking a synchronous code and making it async.Here's the implementation for this call signature:
Also a nitpick: the synchronous logic you're referencing in the examples is not commonly referred to as "callback". Callback is usually referred to functions that are passed as arguments and meant to be executed later when some logic (usually async) settles.
Somehow, the callback pattern was the first thing that came to mind when I read the title of your post:
I thought we're going to be converting
someFunc
to return a Promise instead of relying on the callback (the second argument).Hey this is the stuff I was looking for! I slapped this together in about 5mins! Didn't even think to just use anonymous functions!