0
votes

I know Array.prototype.map is a synchronous operation. On the other hand if the map function is a callback function (asynchronous) undefined will return immediately.

So my question is can the next function safely assume all callback functions have been done?
A sample code may make my question more clear :

results = files.map(file => {
  fs.readFile(file, (err, data) => {
    if (err) throw err;
    return process(file) //will return the processed value, NOT a promise
  });
)
//I know results will be [undefined, undefined, undefined ...]
//But can I assume all the files have been processed if I reach here?
console.log('done')

I don't care about the return values. That is why I don't want to bother with await/async. I just want to make sure all callback functions have called and returned. Is that possible ?

------- update --------

In additional to the answer I found these articles also help me understand the problem: https://medium.com/@antonioval/making-array-iteration-easy-when-using-async-await-6315c3225838
Using async/await with a forEach loop

I have to use promise to make sure all callback iteratees have finished. So using bluebird promise.map helps to reduce boilerplate codes

1
You actually return nothing from the arrow func, therefore it is undefined, if you return the promise you could use Promise.all on the returned array.Jonas Wilms
I don't want to use await b/c I can't care about the mapped array I just want to know if all callback functions are returned. What is the "correct" way to do it ?Qiulang 邱朗
@JonasWilms my sample code was wrong (I have corrected it) I do return in my arrow function but I believe I still get an array with all undefined items. I think my question is different from what you mentioned in the other two questions.Qiulang 邱朗
Agreed, its not a real dupe, apologiesJonas Wilms
@Qiulang no, map does not ensure that any callbacks have been called, in fact, it doesn't even know about the asynchronous callbacks you passed to readFile. It only cares about the return value of the map callback itself, which is undefined. Just go and use promises, you still can ignore their results - but you need them to be able to wait for them.Bergi

1 Answers

1
votes

You have to make the callback function promising, then you can use Promise.all:

 const results = Promise.all(files.map(file => new Promise(resolve => {
  fs.readFile(file, (err, data) => {
    if (err) throw err;
    resolve(process(file));
  });
 ));

 results.then(() => {
   console.log('done')
   //...
 });