1

I have the following exercise:

const { promisify } = require('util')

const print = (err, contents) => { 
  if (err) console.error(err)
  else console.log(contents) 
}

const opA = (cb) => {
  setTimeout(() => {
    cb(null,'A')
  }, 500)
}

const opB = (cb) => {
  setTimeout(() => {
    cb(null, 'B')
  }, 250)
}

const opC = (cb) => {
  setTimeout(() => {
    cb(null, 'C')
  }, 125)
}

Without modifying the functions and the cb is it possible to use promisify to transform it into promise based?

UPDATE. I try this solution but it doesn't work as I expect. The print sequence is C B A, while I was expecting A B C

const promA = promisify(opA)
const promB = promisify(opB)
const promC = promisify(opC)
promA(print).then(promB(print)).then(promC(print))

UPDATE II. Solved, thanks everyone :

const promiseA = promisify(opA);
const promiseB = promisify(opB);
const promiseC = promisify(opC);
 
Promise.all([promiseA(),promiseB(),promiseC()]).then((res)=>{
  res.map(val => print(null,val))
})
  • Yes, it's possible. Did you try it? – Bergi Jun 08 '21 at 15:53
  • 2
    If you want to know _how it works_, you can look at the [implementation](https://github.com/nodejs/node/blob/f504c9c6b897f14891f147ad4a05e743133a0d35/lib/internal/util.js#L302-L348), or if you want to know _how to use it_ read [the docs](https://nodejs.org/dist/latest/docs/api/util.html#util_util_promisify_original). I'm not sure what you mean by *"Without modifying the ... cb"* - if you mean `print`, the point of `promisify`ing is that you don't _need_ the callback any more. – jonrsharpe Jun 08 '21 at 15:59
  • as far as I know without changing part of the exercise code it is not possible to use promisify. changing part of the code instead I can use promisify easily. maybe I misunderstood the requests of the exercise, but if not, I ask: without changing the provided code is it possible to transform it into promise based? thanks for your patience – Parenti Davide Jun 08 '21 at 16:30
  • I think we're a little confused by some translation issues here, and so we're a little thrown off by "without changing the provided code". Are you not allowed to change *any* of the existing code, just add to it? What can you touch and what can you not touch? – user3781737 Jun 08 '21 at 16:40
  • @ParentiDavide What part do you need to change? Can you please [edit] your question to include how you would change the code to make it work (in a way that you know to do but are not allowed to use)? – Bergi Jun 08 '21 at 16:48
  • Your amazement suggests that I have not understood the exercise and that it is therefore possible to change the existing code to adapt it to the promise style. Thank you all. – Parenti Davide Jun 08 '21 at 16:49
  • @ParentiDavide You should not need to change the code of `opA`, `opB` and `opC`. Use `util.promisify` to create new functions from them. – Bergi Jun 08 '21 at 16:52
  • i updated the question with the solution i attempted, but it doesn't work as i expect – Parenti Davide Jun 09 '21 at 06:40

1 Answers1

0

I try this solution but it doesn't work as I expect:

promA(print).then(promB(print)).then(promC(print))

After having promisified the functions, you no longer should pass a callback - it's

promA().then(console.log, console.error);

For sequencing them, notice that you still need to pass a function to .then(), not a promise - so it's

promA().then(resA => {
    console.log(resA);
    return promB();
}).then(resB => {
    console.log(resB);
    return promC();
}).then(resC => {
    console.log(resC);
}).catch(err => {
    console.error(err);
});

or flattened to

promA().then(console.log).then(promB).then(console.log).then(promC).then(console.log).catch(console.error);

Notice that the print function with its (error, result) => void signature is only suitable for asynchronous functions with the node.js callback convention, not for promises, that's why I called console.log and console.error directly in the above examples. Error handling is separated better and done differently with promises.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375