Reputation: 1701
There is something I am not understanding about using deferred promises in node.js using the q module. Here is a set up that illustrates my problem.
var Q = require('q');
var http = require('http');
var url = 'http://www.genenames.org/cgi-bin/download?' +
'col=gd_hgnc_id&' +
'col=gd_pub_eg_id&' +
'status=Approved&' +
'status_opt=2&' +
'where=&' +
'order_by=gd_pub_eg_id&' +
'format=text&' +
'limit=&' +
'submit=submit';
httpGet = function (url) {
var deferred = Q.defer();
var body = "";
http.get(url, function(res) {
res.on('data', function(chunk) {
body += chunk;
});
res.on('end', function() {
// WE NEVER GET HERE ...
console.log(body);
deferred.resolve(body);
});
})
.on('error', function(err) {
console.log(err);
});
return deferred.promise;
};
var fetchData = function() {
var deferred = Q.defer();
httpGet(url)
.then(deferred.resolve())
.done();
return deferred.promise;
};
fetchData()
.then(function() {
console.log("I got here before data was downloaded!")
process.exit(0);
})
.catch(function(err) {
throw(err);
})
.done();
In fetchData, the ".then" function gets called before httpGet() is done downloading the data. I do not understand why the .then is executed before the deferred.resolved is called.
If I comment out the deferred.resolve() in fetchData(), then things work as I expect, although then of course the program hangs as the final promise is never fulfilled.
Can someone point out where I am going awry here?
Upvotes: 3
Views: 9120
Reputation: 17454
You're invoking deferred.resolve
immediately. Instead, you want to pass a reference to that function to then
, like this:
.then(deferred.resolve)
Upvotes: 5