Reputation: 1360
I'm getting started with NodeJS with a script (not a webapp), and this is baffling to me. I have the following simplified functions:
var request = require('request');
function first_func(name) {
console.log('first_func(' + name + ')');
var url = 'http://...' + name;
var answers = new Array();
request(url, function(error, resp, html) {
...
answers.push(x);
});
return answers;
}
function second_func(answers) {
var results = new Array();
for (var a in answers) {
var url = 'http://...' + a;
request(url, function(error, resp, html) {
...
results.push(x);
});
}
return results;
}
first_func()
scraps a directory page, and second_func()
scraps the particular page for that entry. The script runs like this at the end of the script:
var names = ['a', 'b', ...];
function main() {
for (var n in names) {
var ans = first_func(names[n]);
console.log('answers: ' + ans);
for (var a in ans) {
second_func(ans[a]);
}
}
}
main();
For some reason NodeJS is doing first_func()
and second_func()
in parallel. Why isn't it waiting for first_func()
to complete before running second_func()
? The output is:
answers: undefined
first_func(a)
first_func(b)
...
Why is NodeJS jumping into that inner for
loop in main()
before waiting for first_func()
to return?
Upvotes: 0
Views: 66
Reputation: 23060
You can use the async module to work around this. It would look something like the following:
var request = require('request');
var async = require('async');
function first_func(name, done) {
console.log('first_func(' + name + ')');
var url = 'http://...' + name;
request(url, function(error, resp, html) {
...
done(answers);
});
}
function second_func(answers, done) {
var results = new Array();
async.each(answers, function(answer, next) {
var url = 'http://...' + a;
request(url, function(error, resp, html) {
...
results.push(x);
next();
});
}, function(err) {
done(results);
});
}
var names = ['a', 'b', ...];
function main() {
async.each(names, function(name, next) {
first_func(name, function(err, answers) {
second_func(answers, function(results) {
// do something wit results
next();
});
});
}, function(err) {
// done will everything
});
}
main();
You basically call a function when you're done getting the values you need instead of returning them. The async module will let you iterate over arrays in an async friendly way.
Upvotes: 1