1

(A prior version of this question was closed as a dup of how to invoke async functions in a loop. This version states clearly that the functions are not async)

I have several callback style functions which cannot be modified. Only changing the ABC function, how can I get the output in the same order as the function present in the D variable. I have tried using async-await but getting the output as ['123', 'ankit', '345'] because of the timeout event.

https://jsfiddle.net/ankitg1602/unrxv3k6

const A = (dev) => {
  setTimeout(() => {
    dev('ankit')
  }, 300)
}

const B = (dev) => {
  setTimeout(() => {
    dev('123')
  }, 50)
}

const C = (dev) => {
  setTimeout(() => {
    dev('345')
  }, 500)
}

const D = [A, B, C]

const ABC = (args, dev) => {
  // write your code here
  Promise.all(D.map(async (fun1) => {
    return await fun1(dev)
  }))
}

ABC(D, (result) => {
   console.log('result:', result) // ['ankit', 123, 345]
})
danh
  • 62,181
  • 10
  • 95
  • 136
Ankit Kumar Gupta
  • 1,256
  • 1
  • 10
  • 23
  • you need to pass a `resolve` function to `A`, etc. – Daniel A. White Dec 30 '21 at 16:29
  • While i somewhat agree the duplicate of your last question isn't all too accurate, it would be more open to at least mention the situation voluntarily (people could see what was already posted). – ASDFGerte Dec 30 '21 at 16:30
  • 1
    None of the functions `A`, `B`, or `C` returns a promise, so unless you pass e.g. a `resolve` callback from a promise constructor (which you don't), there is nothing to `await`. – ASDFGerte Dec 30 '21 at 16:32
  • @DanielA.White https://jsfiddle.net/ankitg1602/unrxv3k6 If you know the answer please edit and share the answer Please. – Ankit Kumar Gupta Dec 30 '21 at 16:35
  • Edited with @ASDFGerte 's suggestion to make clear the relationship to the prior question which failed to articulate the core problem. – danh Dec 30 '21 at 16:37
  • It's two different things to log the results in the wanted order or to time te functions such that they resolve in the wanted order. Which one do you want..? – Redu Dec 30 '21 at 16:41
  • @Redu want output in this order ['ankit', 123, 345] – Ankit Kumar Gupta Dec 30 '21 at 16:44
  • @Redu - agreed. I think the point of the OP is to get results in a pre-determined order (the order of A, B, C) of functions that have arbitrary execution times. – danh Dec 30 '21 at 16:45
  • That's what i am saying. You can get your output in the order that you want by doing two fundamentally different approaches which serve different purposes. Do you want to run the A, B and C functions simultaneously or one after the other to achieve your goal..? – Redu Dec 30 '21 at 16:52

1 Answers1

1

The idea is to promisify the callback style functions. Below, a promise is created for each that resolves when the function calls its callback.

Map over promisfy to produce an array of async functions. Invoke each of them to collect an array of promises, then resolve the promises concurrently with Promse.all()

const A = (dev) => {
  setTimeout(() => {
    dev('ankit')
  }, 300)
}

const B = (dev) => {
  setTimeout(() => {
    dev('123')
  }, 50)
}

const C = (dev) => {
  setTimeout(() => {
    dev('345')
  }, 500)
}

const D = [A, B, C]

const ABC = async(args, dev) => {
  const promisify = fn => () => new Promise(resolve => fn(resolve));
  const promises = args.map(fn => promisify(fn)());
  Promise.all(promises).then(dev)
}

ABC(D, (result) => {
  console.log('result:', result) // ['ankit', 123, 345]
})
danh
  • 62,181
  • 10
  • 95
  • 136