1

I need to implement the following usage for functionA

functionA(url).then((result) => process(result))

The problem is that, to get result, functionA calls an asynchronous functionB inside, and the only way to get result out of functionB is via a callback.

I know the following solution it is definitely wrong, as it returns undefined, but I thought maybe it is a good start

async function functionA(url) {
  return new Promise((resolve, reject) => {
    let outerResult

    const callback = (result) => {
      outerResult = result
    }

    functionB(url, callback)

    resolve(outerResult)
  })
}

PS: the reason functionB can only return values via a callback is that it adds its request for results to a collection of requests, and based on priority the requests are then fired. I cannot think of anyway other than callback to return the result from functionB.

lorraine
  • 124
  • 1
  • 10
  • Why not `resolve(result)` inside `callback` instead of `outerResult = result`? In the current code `resolve(outerResult)` always runs before the callback so the promise always resolves to undefined. What you're asking here appears to be "how do I _promisify_ `functionB`?", or, in general "how do I promisify a callback function?" – ggorlen Apr 23 '21 at 23:01
  • Just `return new Promise(resolve) => { functionB(url, resolve); })`. [That `outerResult` thing does not work](https://stackoverflow.com/q/23667086/1048572)! – Bergi Apr 24 '21 at 02:36

1 Answers1

2

Since functionA returns a Promise and does not use await it is not async.

Since functionB takes a callback you can just pass down your resolve function.

Either with an arrows function:

function functionB(url, cb) {
    // Simulate Some Callback Behaviour
    cb(`${url} + 10`);
}


function functionA(url) {
    return new Promise((resolve, reject) => {
        functionB(url, (result) => {
            resolve(result);
        });
    });
}

function process(result) {
    console.log(result);
}


functionA("sample.com").then((result) => process(result));

Or, simply pass resolve as the callback:

function functionB(url, cb) {
    // Simulate Some Callback behaviour
    cb(`${url} + 10`);
}


function functionA(url) {
    return new Promise((resolve, reject) => {
        functionB(url, resolve);
    });
}

function process(result) {
    console.log(result);
}


functionA("sample.com").then((result) => process(result));
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
  • 1
    Don't "*Do Something Before Resolving*". Do whatever you have to do after resolving, in a `then` handler. – Bergi Apr 24 '21 at 02:37