0

I have the following snippet:

var request = require('request');

var randomNumber1 = 656;
var randomNumber2 = 879;
var dataCollected = []

function printNumberOfCollectedData() {
    console.log('I collected ' + dataCollected.length + ' data so far.');
}

function getAsyncLoadedData(cb) {
    request.get('https://api.bitfinex.com/v2/candles/trade:1m:tBTCUSD/hist?limit=1&end=1517158020000&duration=1800', function (err, res, body) {
        if (err) {
            //TODO: handle err
        }
        if (res.statusCode === 200) {
            console.log(body)
            cb(body)
        } //etc
        //TODO Do something with response
    });
}

for (var n = 0; n < 1000; n++) {
    if (n === randomNumber1) {
        getAsyncLoadedData(function (data) {
            dataCollected.push(data);
        })
    }
    if (n === randomNumber2) {
        printNumberOfCollectedData();
    }
}

My problem is printNumberOfCollectedData should be called only after dataCollected.push(data); Basically, I want to freeze the for loop until getAsyncLoadedData's callback is called.

Community
  • 1
  • 1
TSR
  • 17,242
  • 27
  • 93
  • 197

3 Answers3

0

Maybe async waterfall is what you need? https://www.npmjs.com/package/async-waterfall

It provides a model, where several callback functions are executed one after another and each of those pass their result to the next one.

Noltibus
  • 1,300
  • 3
  • 12
  • 34
0

You should not use a for loop with async code. Try a self-calling function instead:

var max_iterations = 1000;
function loop(n) {
    if (n === randomNumber1) {
        getAsyncLoadedData(function (data) {
            dataCollected.push(data);
            setImmediate(function () { loop(n+1)});
        })
    }
    else if (n === randomNumber2) {
        printNumberOfCollectedData();
        setImmediate(function () { loop(n+1)});
     }
    else if (n < max_iterations) {
        setImmediate(function () { loop(n+1)});
    }
}

loop(0);
  • 1
    Note, "recursion" is not technically possible with asynchronous code; see [What are the boundaries of recursion?](https://stackoverflow.com/questions/40499044/what-are-the-boundaries-of-recursion?), [In JavaScript, what are the differences between “recursion”, “a non-terminating procedure that happens to refer to itself”, and “repeated scheduling”?](https://stackoverflow.com/questions/41292992/in-javascript-what-are-the-differences-between-recursion-a-non-terminating) – guest271314 Jan 28 '18 at 17:33
  • @guest271314 Enter `async`/`await` and suddenly it's plain recursion again… – Bergi Jan 28 '18 at 22:51
  • @Bergi Can you provide a brief summary as to why? Or should that specific Question be asked for clarity and disambiguation as to what "recursion" is relevant to the inclusion of asynchronous code within a `async `function that repeatedly calls (executes) itself where `await` is used within the `async` function? What does `async/await` change when evaluating whether a pattern is "recursion" or "repeated scheduling"? – guest271314 Jan 28 '18 at 22:54
  • @guest271314 you are right, its not recursion. Changed it. – leonardoandrade Jan 29 '18 at 09:15
0

I solved it using async/await function. More details can be found here. I changed the code like this:

async function runForLoop() {

        for (var n = 0; n < 1000; n++) {
        if (n === randomNumber1) {
            await getAsyncLoadedDataPromise(function (data) {
                dataCollected.push(data);
            });
        }
        if (n === randomNumber2) {
            printNumberOfCollectedData();
        }
    }

}
runForLoop()
TSR
  • 17,242
  • 27
  • 93
  • 197