1

I would like to process an XML file in JavaScript, read every sheet asynchronously (because oviously it would be faster), and return the final result. I have the parser functions, I got stuck on the part when I would like to wait for every async call to finish, then return the result. A callback isn't the best practice for me in this case, because this function would be called at the beggining of another module, where I wouldn't like to put the rest of the code (let's say for example 500 lines) in a callback.

I have tried many approaches, the last one looks like the one below. But it seems to result in an infinite loop. All the other attempts returned undefined value, because the caller function ended before async calls would finish, and the accumulator haven't got any value.

1. To collect every async call's result, I used promise.

function getAllSheets(callback) {
    accumulator = {};

    promise.all([
        processOneSheetAsync(workbook, sheetname1, ..., callback(data) {
            accumulator.one = data;
        }),
        processOneSheetAsync(workbook, sheetname2, ..., callback(data) {
            acc.two = data;
        }),
        /* some more function calls */
    ]).then(function(result) {
        callback(acc);
    });
}

Note: processOneSheetAsync() is function that returns a new Promise and calls the parser(), as expected.


2. Then I tried to wait for it's callback in a function like this:

function getResult() {
    var result;
    var callback = false;

    getAllSheets(function(data) {
        result = data;
        callback = true;
    });

    while(!callback){};
    return result;
}

I thought this would block the getResult() function until the variable callback is set to true. However, it seems that the while loop never detects the change of callback's.

Is there any good approach to solve this problem?

Thookes
  • 99
  • 1
  • 7

1 Answers1

0

You should really use a callback. I'd probably do something like:

var myResults=[];
var waiting=0;

data.forEach(function(datum){
    waiting++;
    asyncCall(datum, callback);
}

function callback(result){
    myResults.push(result);
    waiting--;
    if (waiting == 0){
         doStuffOn(myResults);
    }
}

However, if you're still against everything that is good in the world, you should check this, found here

Community
  • 1
  • 1