如何正确使用节点模块

时间:2016-08-01 05:06:52

标签: javascript node.js express node-modules

我是一名具有强大Java背景的CS学生,到目前为止javascript已经成为具有挑战性但又有趣的体验,直到我遇到了我试图使用自己的模块返回需要的值的情况。程序在返回之前等待某些程序的完成。


到目前为止,我发布过这个问题的论坛中没有人能够对问题给出实际的代码修复,他们有我建议阅读与手头问题无关的其他材料。
有人请您阅读代码并为我所面临的问题提供正确的标准解决方案吗? 以下是代码,简单节点服务器应用程序,app.js和天气模块,weatherApp.js,它使用用户提供的邮政编码并返回该地区的天气预报。

这是代码:
weatherApp.js

// The required modules.
var http = require("http");
var https = require("https");


    //result object
    var resultSet = {
        googleRequestUrl:"",
        forecastIOrequest:"",
        latitude :"",
        longitude:"",
        localInfo:"",
        weather:"",
        humidity:"",
        pressure:"",
        time:""
    };

    //print out error messages
    function printError(error){
        console.error(error.message);
    }

    //Forecast API required information:
    //key for the forecast IO app
    var forecast_IO_Key = "bb9aac7c57877f8f5fab339e3b55669a";
    var forecast_IO_Web_Adress = "https://api.forecast.io/forecast/";


    //Create Forecast request string function
    function createForecastRequest(latitude, longitude){
        var request = forecast_IO_Web_Adress + forecast_IO_Key + "/"
                          + latitude +"," + longitude;
        return request;
    }

    //Google GEO API required information:
    //Create Google Geo Request
    var google_GEO_Web_Adress =  "https://maps.googleapis.com/maps/api/geocode/json?address=";

    function createGoogleGeoMapRequest(zipCode){
        var request = google_GEO_Web_Adress+zipCode + "&sensor=false";
        return request;
    }


    // 1- Need to request google for geo locations using a given zip
    function connectToGoogleGEO(zipCode, afterCallback){
        var googleRequest = https.get(createGoogleGeoMapRequest(zipCode), function(response){
            //saving the Google request URL
            resultSet.googleRequestUrl = createGoogleGeoMapRequest(zipCode);
            var body = "";
            var status = response.statusCode;
            //a- Read the data.
            response.on("data", function(chunk){
                body+=chunk;
            });
            //b- Parse the data.
            response.on("end", function(){  
                if(status === 200){
                   try{
                       var googleReport = JSON.parse(body);
                       resultSet.latitude = googleReport.results[0].geometry.location.lat;
                       resultSet.longitude = googleReport.results[0].geometry.location.lng;

             resultSet.localInfo = googleReport.results[0].address_components[0].long_name + ", " +
                                   googleReport.results[0].address_components[1].long_name + ", " +
                                   googleReport.results[0].address_components[2].long_name + ", " +
                                   googleReport.results[0].address_components[3].long_name + ". ";
                                   // callback to forecast IO.

                       afterCallback(resultSet.latitude, resultSet.longitude);  
                   }catch(error){
                       printError(error.message);
                   }finally{
                    // nothing here
                   } 
                }else{
                    printError({message: "Error with GEO API"+http.STATUS_CODES[response.statusCode]})
                }
            });
        });
    }

    function connectToForecastIO(latitude,longitude){
        var forecastRequest = https.get(createForecastRequest(latitude,longitude),function(response){
           resultSet.forecastIOrequest = createForecastRequest(latitude,longitude);
            var body = "";
            var status = response.statusCode;
            //read the data
             response.on("data", function(chunk){
                body+=chunk;
            });
            //parse the data
            response.on("end", function(){
                try{
                    var weatherReport = JSON.parse(body);
                    resultSet.weather = weatherReport.currently.summary;
                    resultSet.humidity = weatherReport.currently.humidity;
                    resultSet.temperature = weatherReport.currently.temperature;
                    resultSet.pressure = weatherReport.currently.pressure;
                    resultSet.time = weatherReport.currently.time; 
                }catch(error){
                    printError(error.message);
                }finally{
                  console.log(resultSet);

                }
            });
        });    
    }


    function get(zipCode){
        var results = connectToGoogleGEO(zipCode, connectToForecastIO);
        return results;
    }

    //define the name of the outer module.
    module.exports.get = get;

这是服务器代码:
app.js

var express = require("express");
var weatherApp = require("./weatherApp.js");
var path = require("path");
var http = require("http");
var app = express();

//creating routes
//The home
app.get("/", function(req, res){
    res.redirect("/weather");
});
app.get("/weather", function(req, res){
   res.sendFile(path.join(__dirname + "/index.html"));
});
//------------------------------------------------------
//The resources, css, web js files, images etc.
app.get("/StyleSheets/style.css", function(req, res){
   res.sendFile(path.join(__dirname + "/StyleSheets/style.css"));
});
app.get("/webScripts/app.js", function(req, res){
   res.sendFile(path.join(__dirname + "/webScripts/app.js"));
});
app.get("/webImages/swirl_pattern.png", function(req, res){
   res.sendFile(path.join(__dirname + "/webImages/swirl_pattern.png"));
});
//-------------------------------------------------------
//other requests

app.get("/zipcode.do", function(req, res){
    var zipcode = req.query["zipcode"];
    var response = "No report Available";

    function getReport(zipCode, callback){
        response = weatherApp.get(req.query["zipcode"]);
    }
    getReport(zipcode, ()=>{
       res.send("<p>" + response+ "</p>"); 
    }); 
});

//any other entry thats not listed as a valid to request
app.get("/:title", function(req,res){
    var title = req.param.title;
    if(title === undefined){
       var status = res.status(503);
        res.send("This page does not exists" + '"' + http.STATUS_CODES[503] + '"');
    }else{
        res.send(title);
    }
});

app.listen(3000, function(){
    console.log("Server running at port: 3000")
});

<小时/> 我现在面临的主要问题是:

  1. 即使天气模块中的最终console.log打印出正确的resultSet对象,程序也不会从模块返回任何内容。
  2. 服务器不等待模块返回,并继续不打印数据。
  3. 有人可以解决任何这些问题,我会非常感激,这确实阻碍了我的进步并打破了我的士气:(

1 个答案:

答案 0 :(得分:0)

您的问题是您正在使用异步函数,就好像它们是同步的一样。

这可能不是唯一的问题,但这个功能特别成问题:

function get(zipCode){
    var results = connectToGoogleGEO(zipCode, connectToForecastIO);
    return results;
}

connectToGoogleGEO()调用the asynchronous https.get() function并且不会返回从Google检索到的数据。您需要重写代码,以便它不希望函数返回数据。相反,您需要传递一个将处理数据的回调。

请注意了解何时调用异步函数以及它们的回调如何工作。在使用Node.js

时,这是至关重要的