循环中的Node.js回调具有错误的迭代器值
Node.js callback within a loop has wrong iterator value
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)
}
我还没有测试过上面的内容,但您可以看到我是如何将请求封装在一个函数中,并将迭代器值作为参数传递给该函数的。
相关文章:
- Babel编译错误:找不到模块核心js/library/fn/get迭代器
- 从两个基于0的for循环迭代器中获取单个基于0的索引的公式
- Rails:试图在javascript(Google Charts API)中嵌入一个adv-ruby(each+迭代器
- 在javascript中,从迭代器创建Array
- Javascript中的迭代器和生成器
- 从迭代器/生成器中获取单个yield值
- 迭代器和可迭代之间的区别
- 文件夹迭代器中的Google驱动器文件迭代器
- DOM:如何根据迭代器值设置元素宽度并在mouseover上调用函数
- javascript中多维数组的迭代器
- 迭代Promise迭代器的非递归方法
- 循环中的Node.js回调具有错误的迭代器值
- underscore.js,迭代器引用错误
- 去掉foreach中的自定义绑定以获取迭代器
- 迭代器中的return element.parentNode
- 如何使用量角器+angular获取迭代器索引/键
- 警告:数组或迭代器中的每个子节点都应该有一个唯一的“键”道具
- ES6中是否有收集迭代器的功能,包括最终返回值
- 数组或迭代器中的每一个子元素都应该有一个唯一的“键”.道具
- 递归迭代器上的最大调用堆栈大小错误