Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NodeJs: util.promisify where the callback function has multiple arguments

Tags:

node.js

I may be missing something really obvious here, but how do I use util.promisify with a function which looks like this?

function awkwardFunction (options, data, callback) {
    // do stuff ...
    let item = "stuff message"
    return callback(null, response, item)
}

Which I can call like this:

 awkwardFunction ({doIt: true},'some data', (err, result, item) => {
      console.log('result')
      console.log(result)
      console.log('item')
      console.log(item)
      done()
    })

And get back

result
{ data: 'some data' }
item
stuff message

When using the promisified version:

let kptest = require('util').promisify(awkwardFunction)
kptest({doIt: true},'some data')
   .then((response, item) => {
    console.log('response')
    console.log(response)
    console.log('item')
    console.log(item)

 })
 .catch(err => {
     console.log(err)
  })

and trying to access both "response" and "item", it seems the 2nd param is ignored...

result
{ data: 'some data' }
item
undefined

Is there a way to do this WITHOUT changing the function (in reality, it is a library function, so I can't).

like image 733
kpollock Avatar asked Jan 04 '19 12:01

kpollock


People also ask

What is util Promisify in node JS?

The util. promisify() method basically takes a function as an input that follows the common Node. js callback style, i.e., with a (err, value) and returns a version of the same that returns a promise instead of a callback.

How do you Promisify callbacks?

promisify() function is not available. The idea is to create a new Promise object that wraps around the callback function. If the callback function returns an error, we reject the Promise with the error. If the callback function returns non-error output, we resolve the Promise with the output.

What is the purpose of Util Promisify?

The util. promisify() method defines in utilities module of Node. js standard library. It is basically used to convert a method that returns responses using a callback function to return responses in a promise object.


2 Answers

util.promisify is intended to be used with Node-style callbacks with function (err, result): void signature.

Multiple arguments can be treated manually:

let kptest = require('util').promisify(
  (options, data, cb) => awkwardFunction(
    options,
    data,
    (err, ...results) => cb(err, results)
  )
)

kptest({doIt: true},'some data')
.then(([response, item]) => {...});

In case more sophisticated functionality is wanted, some third-party solution like pify can be used instead of util.promisify, it has multiArgs option to cover this case.

like image 102
Estus Flask Avatar answered Sep 21 '22 15:09

Estus Flask


You could make your own promisify, where you return a promise that resolves with the arguments of the callback and on the then block you destructure them. Hope this helps.

function awkwardFunction (options, data, callback) {
    // do stuff ...
    let item = "stuff message";
    return callback(null, data, item);
}

const mypromisify = (fn) =>
    (...args) =>
        new Promise(resolve =>
            fn(...args,
                (...a) => resolve(a)
            )
        );

const kptest = mypromisify(awkwardFunction);

kptest({ doIt: true }, 'some data')
    .then(([error, response, item]) => {
        console.log(response);
        console.log(item);
    })
    .catch(err => {
        console.log(err);
    });
like image 40
Alex G Avatar answered Sep 19 '22 15:09

Alex G