I'm writing a Node.js module that queries the GitHub API to find out which of the user's repos have a gh-pages
branch. Here's the code:
// index.js
var https = require('https');
var spawn = require('child_process').spawn;
module.exports = function(user, auth_token) {
// Normally this would be another API call but I'm simplifying
var repos = ['android', 'colortime.js', 'strugee.github.com'];
for (var i in repos) {
var repo = repos[i];
console.log('running for loop with repo =', repo);
https.get({
hostname: 'api.github.com',
path: '/repos/strugee/' + repo + '/branches',
headers: {'User-Agent': 'gh-pages-bootstrap/1.0.0', Authorization: 'token ' + auth_token}
}, function(res) {
console.log('calling https callback with repo =', repo);
});
}
};
I've put this module in a CLI wrapper (source included so that you can more easily test the module):
// cli.js
var ghauth = require('ghauth');
var ghpages = require('./index.js');
var authOptions = {
configName: 'gh-pages-bootstrap',
scopes: ['public_repo'],
note: 'gh-pages-bootstrap',
userAgent: 'gh-pages-bootstrap/1.0.0'
};
ghauth(authOptions, function(err, authData) {
if (err) throw err;
ghpages(authData.user, authData.token);
});
which spits out the following:
running for loop with repo = android
running for loop with repo = colortime.js
running for loop with repo = strugee.github.com
calling https callback with repo = strugee.github.com
calling https callback with repo = strugee.github.com
calling https callback with repo = strugee.github.com
As you can see, the callback always thinks that repo
is the same thing. Obviously the problem is that by the time the response headers have been received and the callback is fired, the for loop is already finished. However, despite that knowledge, I cannot for the life of me figure out how to get the callback to use the right value of repo
. At least, not without blocking the event loop (which is obviously unideal).
I'm pretty sure that I'm missing some rule about variable scope, and I think the prototype model may be involved or something, which is very confusing.
How can I solve this concurrency problem?