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
});