NodeJS回调问题,找不到数据

时间:2016-12-09 15:31:49

标签: javascript node.js scrape

我试图通过使用请求模块进行抓取和收集来将一些信息转换为变量。我的猜测是我无法在temp_table变量中显示结果,因为它没有在正确的时间执行,因为请求方法是异步的而console.log(temp_table)不是。

我考虑过为我的代码添加一个回调,但我不知道在哪里添加它,给下面的代码库。

我的兴趣在于使用请求函数填充数组temp_table,该函数的运行次数与places数组的长度一样多。

---------------------------------------------- < / H2>
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

提前感谢您的帮助。

编辑:将其标记为副本而不实际帮助我根本没有帮助。在发布问题之前我确实搜索了答案,但我没有提出答案,因此问题。

1 个答案:

答案 0 :(得分:0)

正如您在上述问题中所述,您是对的 由于您正在使用异步功能,因此必须使用回调函数

的解决方案的 首先:将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
});