for(var i in companyTickerList) {
console.log('i = ' + i);
//construct url
var url = base_url + companyTickerList[i];
console.log('url = ' + url);
request(url, function(error, response, xml) {
if(!error && response.statusCode == 200) {
//load xml returned from GET to url
var cik_xml = cheerio.load(xml)
console.log('i = ' + i);
//map company ticker symbol to cik value scraped from xml
TickerToCIK[companyTickerList[i]] = cik_xml('company-info cik').text();
console.log('TICKER = ' + companyTickerList[i] + ' CIK = ' + cik_xml('company-info cik').text());
}
}
//CONSOLE LOG OUTPUT
i = 0
http://www.sec.gov/cgi-bin/browse..........SNPS
i = 1
http://www.sec.gov/cgi-bin/browse..........IBM
i = 2
http://www.sec.gov/cgi-bin/browse..........BA
i = 3
http://www.sec.gov/cgi-bin/browse..........GM
i = 4
http://www.sec.gov/cgi-bin/browse..........F
i = 5
http://www.sec.gov/cgi-bin/browse..........C
i = 6
http://www.sec.gov/cgi-bin/browse..........CVX
i = 6
TICKER = CVX CIK = 0000883241
i = 6
TICKER = CVX CIK = 0000037996
i = 6
TICKER = CVX CIK = 0000831001
i = 6
TICKER = CVX CIK = 0000093410
i = 6
TICKER = CVX CIK = 0001467858
i = 6
TICKER = CVX CIK = 0000012927
i = 6
TICKER = CVX CIK = 0000051143
为什么每次触发请求调用后,回调函数中的迭代器值i总是等于6?它使我的TickerToCIK地图的密钥始终是CVX。我需要将I作为参数传递给回调函数吗?
var
很棘手:)JavaScript实际上是这样评估代码的:
var i;
for(i in companyTickerList) {
console.log('i = ' + i);
// ...
意思是,这就像在第一行代码之前执行的var
定义。
因此,您实际上有一个变量i
,它被更新了6次,最终更新为i = 6
。
您的request()
回调是async,当您的第一个回调被实际调用时,循环早已结束,i
等于6。
解决方案:
一种可能的解决方案是使用IIFE(立即调用函数表达式)。
即:
(function (i) {
// async code using i
})(i);
像这样:
for (var i in companyTickerList) {
console.log('i = ' + i);
//construct url
var url = base_url + companyTickerList[i];
console.log('url = ' + url);
(function (i) {
request(url, function (error, response, xml) {
if (!error && response.statusCode == 200) {
//load xml returned from GET to url
var cik_xml = cheerio.load(xml);
console.log('i = ' + i);
//map company ticker symbol to cik value scraped from xml
TickerToCIK[companyTickerList[i]] = cik_xml('company-info cik').text();
console.log('TICKER = ' + companyTickerList[i] + ' CIK = ' + cik_xml('company-info cik').text());
}
});
})(i);
}
您需要使用闭包来正确实现这一点。例如,像这样的东西。
for(var i in companyTickerList) {
console.log('i = ' + i);
//construct url
var url = base_url + companyTickerList[i];
console.log('url = ' + url);
function(i){
request(url, functon(error, response, xml) {
if(!error && response.statusCode == 200) {
//load xml returned from GET to url
var cik_xml = cheerio.load(xml)
console.log('i = ' + i);
//map company ticker symbol to cik value scraped from xml
TickerToCIK[companyTickerList[i]] = cik_xml('company-info cik').text();
console.log('TICKER = ' + companyTickerList[i] + ' CIK = ' + cik_xml('company-info cik').text());
}
}
}(i)
}
我还没有测试过上面的内容,但您可以看到我是如何将请求封装在一个函数中,并将迭代器值作为参数传递给该函数的。