编辑:已更新为完整代码。
我在node.js中编写javascript代码,这是为了遍历我从网上抓取的数据数组。代码的目的是:
1)检查播放器表格以查看该播放器的名称是否存在于记录中,并且 2)如果该播放器不存在,请将他添加到数据库中。
这是我的代码:
var cheerio = require('cheerio');
var request = require('request');
var data = [];
var mysql = require('mysql');
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'blahblah',
database: 'test',
port: 3306 });
connection.connect();
request('http://www.basketball-reference.com/friv/dailyleaders.cgi?month=12&day=28&year=2014', function(err, response, body){
if(!err && response.statusCode ==200){
var $ = cheerio.load(body);
$('td', 'tbody').each(function(){
var url = $(this).attr('href');
var text = $(this).text();
data.push(text);
});
for(i=1;i<data.length;i+=26){
var query = connection.query(
"SELECT * FROM player WHERE name = '"+data[i]+"'",function(err, result, fields) {
if (err) throw err;
if(result.length==0){
//var insertQuery = "INSERT INTO player (provider_id, team_id, position_id, name) VALUES (1, (SELECT id FROM team WHERE slug = '"+data[i+1]+"'),1,'"+data[i]+"');";
console.log(i);
}
});
}
}
});
请注意,我为了测试目的而注释掉了我的INSERT查询,但是当队名在数据[i + 1]中时,玩家名称位于data [i]中。
为了测试,我只是将i打印到控制台,并且每个循环都打印出i的最大值,即3225.但是,该console.log命令是INSIDE for for循环,所以不应该打印i的每个值增加了吗?
答案 0 :(得分:2)
这与此问题类似:JavaScript closure inside loops – simple practical example
这个答案解释了为什么事情按照他们的方式行事。
如果您在回调中引用变量并且该变量在执行回调之前已经处于该最大值,则会在闭包中发生这种情况。
以下是您的代码正在执行的操作示例(回调错误):
function a(){
var i = 0;
var callbacks = [];
for (i=0;i<100;i+=25){
callbacks.push(function(){
alert(i);
});
}
return callbacks;
}
var callbackArray = a();
for( f in callbackArray){
callbackArray[f]();
}
这是它应该做的事情:
function createFunction(i){
return function(){
alert(i);
}
}
function a(){
var i = 0;
var callbacks = [];
for (i=0;i<100;i+=25){
callbacks.push(createFunction(i));
}
return callbacks;
}
var callbackArray = a();
for( f in callbackArray){
callbackArray[f]();
}
对于您的修复,您应该执行以下操作:
// outside of the code you posted, as a separate function.
function createPlayerSelectionCallback(data,i){
return function(err, result, fields) {
if (err) throw err;
if(result.length==0){
//var insertQuery = "INSERT INTO player (provider_id, team_id, position_id, name) VALUES (1, (SELECT id FROM team WHERE slug = '"+data[i+1]+"'),1,'"+data[i]+"');";
console.log(i);
}
}
}
// this for loop stays in the same place, just modified to use the new function.
for(i=1;i<data.length;i+=26){
var query = connection.query(
"SELECT * FROM player WHERE name = '"+data[i]+"'",createPlayerSelectionCallback(data, i))
}