Reputation: 19855
I am trying to download a web-page using nodejs, javascript. However it seems to have a inifinite loop. Why?
var downloadFinished = false;
var downloadPage = function(url,file) {
rest.get(url).on('complete', function(result) {
if (result instanceof Error) {
console.log('Error:', result.message);
} else {
fs.writeFileSync(file, result, 'utf8');
downloadFinished = true;
}
});
};
if(require.main == module) {
downloadPage('http://google.com', 'new.html');
while(!downloadFinished) {
// wait till download finished.
}
// do other stuff make sure download is finished to 'new.html'
}
Upvotes: 0
Views: 49
Reputation: 3389
When you call that while(!downloadFinished)
it is set to false so you are basically doing while(true)
.
You can use a callback instead of a while loop.
var successCallback = function() {
//do stuff here.
};
var downloadPage = function(url, file, callback) {
rest.get(url).on('complete', function(result) {
if (result instanceof Error) {
console.log('Error:', result.message);
} else {
fs.writeFile(file, result, 'utf8', callback);
}
});
};
if(require.main == module) {
downloadPage('http://google.com', 'new.html', successCallback);
}
Check out Promises they will really help you here. You could use Bluebird a nice Promise library you can just add to your package dependencies.
Upvotes: 1
Reputation: 141927
Javascript is single-threaded, if you have a loop like:
while(!downloadFinished) {
}
that loop will keep running forever and no other function will run (your .on('complete'
callback can't execute until the while loop finishes, because of the single-threaded nature of Javascript, so it won't ever finish since you don't set downloadFinished = true
inside that loop or use a break
statement).
To work around this, you can do all your other stuff in a callback which you don't call until the download completed:
var downloadPage = function(url, file, callback) {
rest.get(url).on('complete', function(result) {
if (result instanceof Error) {
console.log('Error:', result.message);
} else {
/* Don't use writeFileSync, unless you want to block your server,
from handling any requests at all until the disk IO completes
fs.writeFileSync(file, result, 'utf8');
callback();
*/
fs.writeFile(file, result, 'utf8', callback);
}
});
};
if(require.main == module) {
downloadPage('http://google.com', 'new.html', function after_download(){
// do other stuff make sure download is finished to 'new.html'
});
}
Upvotes: 4