HiveBrain v1.2.0
Get Started
← Back to all entries
snippetjavascriptTip

Make a JavaScript function return a promise

Submitted by: @import:30-seconds-of-code··
0
Viewed 0 times
javascriptmakefunctionreturnpromise

Problem

Have you ever wanted to convert an asynchronous function to return a promise in JavaScript? For example, you might want to perform some I/O or use setTimeout() to delay the execution of a function. It's generally pretty straightforward, once you understand the basics of promises.
> [!TIP]
>
> In Node.js 8 or newer, you can use util.promisify to do this.
In essence, we want to wrap a function in a promise, thus we want to create a higher-order function that takes a function as an argument and returns a new function that returns a promise. This new function will call the original function and resolve the promise with the result.

Solution

const promisify = func => (...args) =>
  new Promise((resolve, reject) =>
    func(...args, (err, result) => (err ? reject(err) : resolve(result)))
  );

const delay = promisify((d, cb) => setTimeout(cb, d));
delay(2000).then(() => console.log('Hi!')); // Promise resolves after 2s


>
> In Node.js 8 or newer, you can use util.promisify to do this.
In essence, we want to wrap a function in a promise, thus we want to create a higher-order function that takes a function as an argument and returns a new function that returns a promise. This new function will call the original function and resolve the promise with the result.
Then, we can use variadic arguments to pass in all the arguments to the original function. This way, we can create a new function that can be called with any number of arguments, just like the original function.
Finally, we can use the Promise() constructor to create a new promise, and call the original function with the provided arguments. Depending on the result of the function, we can either resolve the promise with the result or reject it with an error.

Code Snippets

const promisify = func => (...args) =>
  new Promise((resolve, reject) =>
    func(...args, (err, result) => (err ? reject(err) : resolve(result)))
  );

const delay = promisify((d, cb) => setTimeout(cb, d));
delay(2000).then(() => console.log('Hi!')); // Promise resolves after 2s

Context

From 30-seconds-of-code: promisify

Revisions (0)

No revisions yet.