NodeJS 回调问题,找不到数据
NodeJS Callback issue, can't find data
我试图通过使用请求模块进行抓取和收集来将一些信息放入变量中。我的猜测是我无法在 temp_table
变量中显示结果,因为它没有在正确的时间执行,因为请求方法是异步的,而 console.log(temp_table)
不是。
我想在我的代码中添加一个回调,但我不知道在哪里添加它,下面给出了代码库。
我的兴趣是用请求函数的结果填充数组 temp_table
,该函数的长度是 places
数组长度的 运行 倍。
-------------------------------------------- -
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var places = [
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Empoli&c=2635&gm=10&g=1&lang=ita',
'city' : 'a town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Roma&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Firenze&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
];
var temp_table = [];
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
temp = $(".datatable .expa").html();
var h = [], t = [], u = [];
// temp contains the data from the website in html format, it is rewritten in each iteration
var orario = $(".datatable .expa .ora").text().trim();
orario = orario.match(/.{1,2}/g);
for (i = 0; i < 3; i++){
h.push(orario[i]);
}
var temperatura = $(".datatable .expa .col4 span").text().trim();
temperatura = temperatura.match(/\d+\.\d+/g);
ascii_code_temperatura = String.fromCharCode(176);
for (i = 0; i < 3; i++){
t.push(temperatura[i] + ascii_code_temperatura);
}
var humidity = $(".datatable .expa .col10 span:first-child").text().trim();
humidity = humidity.match(/\d+\%/g);
for (i = 0; i < 3; i++){
u.push(humidity[i]);
}
temp_table.push({
"city" : el.city,
"t1" : {
"ora" : h[0],
"temperatura" : t[0],
"humidity" : u[0]
},
"t2" : {
"ora" : h[1],
"temperatura" : t[1],
"humidity" : u[1]
},
"t3" : {
"ora" : h[2],
"temperatura" : t[2],
"humidity" : u[2]
}
});
} else {
console.log("We’ve encountered an error: " + error);
}
//temp_table is readable here
});
//temp_table is empty here, probably because of callback
console.log(temp_table)
// THIS ONE UP HERE IS NOT READ, IT LOGS AN EMPTY ARRAY EACH TIME
}); // FOREACH END
console.log(temp_table)
// THIS ONE UP HERE IS NOT READ, IT LOGS NOTHING
在此先感谢您的帮助。
编辑:在没有真正帮助我的情况下将其标记为重复根本没有帮助。我确实在发布问题之前搜索了答案,但我没有想出答案,因此提出了这个问题。
正如你在上面的问题中所说的那样,你是对的
由于您使用的是异步函数,因此您必须使用回调函数
解决方案
首先:将 foreach 包装在一个函数中
function myfunction(callback) {
声明一个变量,每次回调完成时该变量都会递增
var itemsProcessed = 0;
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
// other code
回调完成后加1
itemsProcessed++;
检查您的 itemsProcessed 值现在是否等于数组的总数,这意味着您的 foreach 现在已完成
if (itemsProcessed == luoghi.length) {
然后在之后调用你传递的回调并且也传递 temp_table
return callback(temp_table);
}
})
}
然后调用此函数并获取 temp_table
的正确值
myfunction(function(temp_table) { // your callback
console.log(temp_table);
})
所以你的代码应该是这样的
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var places = [
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Empoli&c=2635&gm=10&g=1&lang=ita',
'city' : 'a town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Roma&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Firenze&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
];
var temp_table = [];
function get_temp_table(callback) {
var itemsProcessed = 0;
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
temp = $(".datatable .expa").html();
var h = [], t = [], u = [];
// temp contains the data from the website in html format, it is rewritten in each iteration
var orario = $(".datatable .expa .ora").text().trim();
orario = orario.match(/.{1,2}/g);
for (i = 0; i < 3; i++){
h.push(orario[i]);
}
var temperatura = $(".datatable .expa .col4 span").text().trim();
temperatura = temperatura.match(/\d+\.\d+/g);
ascii_code_temperatura = String.fromCharCode(176);
for (i = 0; i < 3; i++){
t.push(temperatura[i] + ascii_code_temperatura);
}
var humidity = $(".datatable .expa .col10 span:first-child").text().trim();
humidity = humidity.match(/\d+\%/g);
for (i = 0; i < 3; i++){
u.push(humidity[i]);
}
temp_table.push({
"city" : el.city,
"t1" : {
"ora" : h[0],
"temperatura" : t[0],
"humidity" : u[0]
},
"t2" : {
"ora" : h[1],
"temperatura" : t[1],
"humidity" : u[1]
},
"t3" : {
"ora" : h[2],
"temperatura" : t[2],
"humidity" : u[2]
}
});
} else {
console.log("We’ve encountered an error: " + error);
}
//temp_table is readable here
itemsProcessed++;
if (itemsProcessed == luoghi.length) {
return callback(temp_table);
}
});
}); // FOREACH END
}
get_temp_table(function(temp_table) {
console.log(temp_table); // this should have a result now
});
我试图通过使用请求模块进行抓取和收集来将一些信息放入变量中。我的猜测是我无法在 temp_table
变量中显示结果,因为它没有在正确的时间执行,因为请求方法是异步的,而 console.log(temp_table)
不是。
我想在我的代码中添加一个回调,但我不知道在哪里添加它,下面给出了代码库。
我的兴趣是用请求函数的结果填充数组 temp_table
,该函数的长度是 places
数组长度的 运行 倍。
-------------------------------------------- -
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var places = [
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Empoli&c=2635&gm=10&g=1&lang=ita',
'city' : 'a town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Roma&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Firenze&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
];
var temp_table = [];
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
temp = $(".datatable .expa").html();
var h = [], t = [], u = [];
// temp contains the data from the website in html format, it is rewritten in each iteration
var orario = $(".datatable .expa .ora").text().trim();
orario = orario.match(/.{1,2}/g);
for (i = 0; i < 3; i++){
h.push(orario[i]);
}
var temperatura = $(".datatable .expa .col4 span").text().trim();
temperatura = temperatura.match(/\d+\.\d+/g);
ascii_code_temperatura = String.fromCharCode(176);
for (i = 0; i < 3; i++){
t.push(temperatura[i] + ascii_code_temperatura);
}
var humidity = $(".datatable .expa .col10 span:first-child").text().trim();
humidity = humidity.match(/\d+\%/g);
for (i = 0; i < 3; i++){
u.push(humidity[i]);
}
temp_table.push({
"city" : el.city,
"t1" : {
"ora" : h[0],
"temperatura" : t[0],
"humidity" : u[0]
},
"t2" : {
"ora" : h[1],
"temperatura" : t[1],
"humidity" : u[1]
},
"t3" : {
"ora" : h[2],
"temperatura" : t[2],
"humidity" : u[2]
}
});
} else {
console.log("We’ve encountered an error: " + error);
}
//temp_table is readable here
});
//temp_table is empty here, probably because of callback
console.log(temp_table)
// THIS ONE UP HERE IS NOT READ, IT LOGS AN EMPTY ARRAY EACH TIME
}); // FOREACH END
console.log(temp_table)
// THIS ONE UP HERE IS NOT READ, IT LOGS NOTHING
在此先感谢您的帮助。
编辑:在没有真正帮助我的情况下将其标记为重复根本没有帮助。我确实在发布问题之前搜索了答案,但我没有想出答案,因此提出了这个问题。
正如你在上面的问题中所说的那样,你是对的 由于您使用的是异步函数,因此您必须使用回调函数
解决方案 首先:将 foreach 包装在一个函数中
function myfunction(callback) {
声明一个变量,每次回调完成时该变量都会递增
var itemsProcessed = 0;
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
// other code
回调完成后加1
itemsProcessed++;
检查您的 itemsProcessed 值现在是否等于数组的总数,这意味着您的 foreach 现在已完成
if (itemsProcessed == luoghi.length) {
然后在之后调用你传递的回调并且也传递 temp_table
return callback(temp_table);
}
})
}
然后调用此函数并获取 temp_table
myfunction(function(temp_table) { // your callback
console.log(temp_table);
})
所以你的代码应该是这样的
var request = require("request"),
cheerio = require("cheerio"),
fs = require("fs");
var places = [
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Empoli&c=2635&gm=10&g=1&lang=ita',
'city' : 'a town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Roma&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
{
'url' : 'http://www.ilmeteo.it/portale/meteo/previsioni.php?citta=Firenze&c=2635&gm=10&g=1&lang=ita',
'city' : 'another town'}
];
var temp_table = [];
function get_temp_table(callback) {
var itemsProcessed = 0;
luoghi.forEach(function(el){
request(el.url, function (error, response, body) {
if (!error) {
var $ = cheerio.load(body);
temp = $(".datatable .expa").html();
var h = [], t = [], u = [];
// temp contains the data from the website in html format, it is rewritten in each iteration
var orario = $(".datatable .expa .ora").text().trim();
orario = orario.match(/.{1,2}/g);
for (i = 0; i < 3; i++){
h.push(orario[i]);
}
var temperatura = $(".datatable .expa .col4 span").text().trim();
temperatura = temperatura.match(/\d+\.\d+/g);
ascii_code_temperatura = String.fromCharCode(176);
for (i = 0; i < 3; i++){
t.push(temperatura[i] + ascii_code_temperatura);
}
var humidity = $(".datatable .expa .col10 span:first-child").text().trim();
humidity = humidity.match(/\d+\%/g);
for (i = 0; i < 3; i++){
u.push(humidity[i]);
}
temp_table.push({
"city" : el.city,
"t1" : {
"ora" : h[0],
"temperatura" : t[0],
"humidity" : u[0]
},
"t2" : {
"ora" : h[1],
"temperatura" : t[1],
"humidity" : u[1]
},
"t3" : {
"ora" : h[2],
"temperatura" : t[2],
"humidity" : u[2]
}
});
} else {
console.log("We’ve encountered an error: " + error);
}
//temp_table is readable here
itemsProcessed++;
if (itemsProcessed == luoghi.length) {
return callback(temp_table);
}
});
}); // FOREACH END
}
get_temp_table(function(temp_table) {
console.log(temp_table); // this should have a result now
});