1

How to implement a callback in getValue1 function ?

Now I getting undefined ?

I need to get "B" value in getAll function

getAll function needs to return a promise and the getValue1 function cannot be changed. How can I do it differently?

function getValue1(callback) {
  setTimeout(() => {
      callback("B");
  }, 10);
}

function getAll() {
   return Promise.all([getValue1(b => b)]);
}

getAll().then((arr) => console.log(arr));

X.Mart
  • 47
  • 6
  • this is odd code ... why are you using Promise.all for code that doesn't use promises? You'll need to return a Promise from `getValue1` rather than using a callback argument i fyou want to easily use it in `Promise.all` – Jaromanda X Oct 11 '20 at 06:05
  • getAll needs to return a promise and the getValue1 function cannot be changed. How can I do it differently? – X.Mart Oct 11 '20 at 06:08
  • function getValue1 I cannot be changed, how to implement callback ? – X.Mart Oct 11 '20 at 06:11

2 Answers2

2

Create a function to wrap the call for getValue1 in such a way that it resolves to the value returned by the callback

i.e. const pvalue = () => new Promise(resolve => getValue1(resolve));

Note, this is the same as

function pvalue() {
  return new Promise(function(resolve) {
    getValue1(value => resolve(value));
  });
}

So, value => resolve(value)

Is your callback to getValue1 - resolving the Promise returned by pvalue

and of course,

getValue1(value => resolve(value));

is equivalent to

getValue1(resolve);

So, then you can call pvalue() instead of getValue1(b=>b) in your Promise.all

function getValue1(callback) {
    setTimeout(() => {
        callback("B");
    }, 10);
}
const pvalue = () => new Promise(resolve => getValue1(resolve));

function getAll() {
    return Promise.all([pvalue()]);
}

getAll().then((arr) => console.log(arr));
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
0

Continuation-passing style, ie "callbacks", and Promises are two differing kinds of machinery for handling asynchronous code. Historically, JavaScript and Node used Function callbacks and the programmer was expected to follow certain conventions to write their code. Because it's hard to follow an unenforced convention, writing callback code was notoriously prone to error. Promises are a newer first-class data structure that offers more features specifically designed for handling asynchrony.


if you write getValue1,

The JavaScript community at large has widely accepted Promises and even more features have been added to the language to take advantage of their ubiquity. You should be writing Promise-based code wherever you can. That means if you are the writer of getValue1, it should not take a callback, and instead return a promise -

const delay = (ms, value) =>
  new Promise(r => setTimeout(r, ms, value))

const getValue1 = _ =>
  delay(2000, "B")

getValue1().then(console.log, console.error)

console.log("please wait...")

You can write getValue1 using continuation-passing style, if you wish. Node.js uses a convention where any error, if present, will be the first argument to the callback. In Node, you must always check for the presence of an error in your callback, otherwise you may be introducing bugs in your program. To follow this convention, your code would look like -

const getValue1 = (callback) =>
  setTimeout(_ => callback(null, "B"), 2000)

getValue1((err, res) => {
  if (err)
    console.error("error encountered:", err.message)
  else
    console.log("result:", res)
})

console.log("please wait...")

if you inherit getValue1,

When you inherit callback style function it's beneficial to convert it so you can use it with newer Promise-based code. Node.js has a built-in function, util.promisify, to do just that. For demonstration purposes, I included my own promisify in the example below -

const promisify = f => (...a) =>              // <- util.promisify
  new Promise
    ( (resolve, reject) =>
        f(...a, (e, v) => e ? reject(e) : resolve(v))
    )

const getValue1 = (callback) =>               // <- old code
  setTimeout(_ => callback(null, "B"), 2000)

const _getValue1 =
  promisify(getValue1)                        // <- promisify old code
  
_getValue1().then(console.log, console.error) // <- back to sanity

console.log("please wait...")

buy-in to the Promise

Promises allow you to leverage new language features like async and await, dramatically improving the code reading and writing experience -

const sleep = ms =>
  new Promise(r => setTimeout(r, ms))

async function getValue1 ()
{ await sleep(1000)
  console.log("loading: 25%...")
  await sleep(1000)
  console.log("loading: 50%...")
  await sleep(1000)
  console.log("loading: 75%...")
  await sleep(1000)
  return "B"
}

async function main()
{ console.log("please wait...")
  const result = await getValue1()
  console.log("done:", result)
}

main().catch(console.error)
please wait...
loading: 25%...
loading: 50%...
loading: 75%...
done: B
Mulan
  • 129,518
  • 31
  • 228
  • 259