如何正确使用节点模块
How to use node modules correctly
我是一名CS学生,有着强大的Java背景,到目前为止,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")
});
我现在遇到的主要问题是:
- 即使天气模块中的final console.log打印正确的resultSet对象,程序也不会从模块返回任何内容
- 服务器没有等待模块返回,并且继续不打印任何数据
有人能为这些问题中的任何一个提供有效的解决方案吗?我真的很感激,这真的阻碍了我的进步,也让我的士气有点低落:(
您的问题是使用异步函数,就好像它们是同步的一样。
这可能不是这里唯一的问题,但这个功能特别有问题:
function get(zipCode){
var results = connectToGoogleGEO(zipCode, connectToForecastIO);
return results;
}
connectToGoogleGEO()
调用异步https.get()
函数,不返回从Google检索到的数据。您需要重写代码,这样它就不会期望函数返回数据。相反,您需要传递一个回调来处理数据。
请注意,何时调用异步函数以及它们的回调是如何工作的。这是使用Node.js 时的基础
相关文章:
- 节点模块依赖关系
- 如何引用HTML中节点模块中的js文件
- 未定义应为节点模块的对象
- 如何在客户端javascript中需要节点模块
- 如何在节点模块中从命令行运行函数
- 将节点模块添加到gitignore
- 使用Q节点模块时,Bluemix node.js应用程序部署失败
- 使用document.cookie将客户端javascript转换为节点模块
- 查找与锁定和更新调度相关的一个或两个节点模块
- 节点模块的可能结构
- 节点模块对象范围:在所有函数之间共享一个对象
- 有没有一种方法可以使用javascript和节点模块(oracledb)将csv导入oracle数据库
- 单元测试节点模块与mocha,模块变量行为怪异
- 要安装依赖项的自定义节点模块
- Node.js如何将链接标记解析为节点模块
- 如何公开JS节点模块
- 如何访问节点模块中具有相对路径的文件
- 节点模块和常规javascript文件之间的区别是什么
- Npm.require可以'找不到节点模块
- 将参数传递给基于类的节点模块