如何正确使用节点模块

问题描述:

我是一名具有强大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. 服务器不在等待模块返回,而是继续不打印任何数据。

有人可以提供一个工作修复任何这些问题,我将非常感激,这确实阻碍了我的进步,打破我的士气有点:(

你的问题是,你正在使用异步。功能就好像它们是同步

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

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

connectToGoogleGEO()电话the asynchronous https.get() function,并且不会返回从Google检索到的数据。你需要重写你的代码,以防止数据被函数返回。相反,您需要传递一个处理数据的回调函数。

请注意知道您何时调用异步函数以及它们的回调是如何工作的。这是使用Node.js时的基础