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

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).

Best Answer

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.

Related Topic