如何在nodejs中管理依赖函数

时间:2016-07-26 04:02:32

标签: express

我正在尝试自学nodejs和expressjs,但是来自java和c ++,这很难习惯。

我制作了一个简单而混乱的模块,它应该返回给定邮政编码的天气预报。

发生这种情况的方法是使用用户邮政编码并使用google api生成该邮政编码的地理坐标。我从JASON文件中获取坐标,然后将它们提供给下一个api调用,此调用是对forecast.io api进行的,这次该位置的天气数据也来自JASON文件。

来自java并且JavaScript的背景不那么扎实我很难让这两个函数相互等待,在这种情况下我需要先调用google api才能完成,因为第二次api调用需要它将提供的坐标。


有人可以查看这段代码并告诉我我使用的策略是否正确/提供建议以便我知道什么是在这种情况下在javascript中完成。 这是代码:

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

//result object
var resultSet = {
    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 = "this is my key, not publishing for security reasons";
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;
}

function get(zipCode){
    // 1- Need to request google for geo locations using a given zip
    var googleRequest = https.get(createGoogleGeoMapRequest(zipCode), function(response){
        //console.log(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 coordinates = JSON.parse(body);
                   resultSet.latitude = coordinates.results[0].geometry.location.lat;
                   resultSet.longitude = coordinates.results[0].geometry.location.lng;

                   resultSet.localInfo = coordinates.results[0].address_components[0].long_name + ", " +
                               coordinates.results[0].address_components[1].long_name + ", " +
                               coordinates.results[0].address_components[2].long_name + ", " +
                               coordinates.results[0].address_components[3].long_name + ". ";
               }catch(error){
                   printError(error.message);
               }finally{
                  connectToForecastIO(resultSet.latitude,resultSet.longitude);
               } 
            }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){
           // console.log(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{
                    return resultSet;
                }
            });
        });    
    }
}


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

是否正确放置了返回语句?我最终在这里使用了吗?请注意,我来自java背景,在java中完全可以使用try {} catch(){}和最后{}块来执行闭包代码,这是我管理这个模块的唯一方法。但是现在我已经合并了一些Express,我尝试从另一个模块执行这个模块的方法,我得到的是一个未定义的返回。

1 个答案:

答案 0 :(得分:0)

你可以使用Promise API,有点像Java中的Futures,所以基本上你可以做的是将两个函数包装在promises中,你可以等待解析来执行下一个函数

var googleRequest = function(zipcode) {
  return new Promise(function(resolve, reject) {
    var request = https.get(createGoogleGeoMapRequest(zipCode), function(response) {
      if (response.statusCode !== 200) {
        reject(new Error('Failed to get request status:' + response.statusCode));
      }
      var body = "";
      //a- Read the data.
      response.on("data", function(chunk) {
          body+=chunk;
      });
      //b- Parse the data.
      response.on("end", function(body) {
        var coordinates = JSON.parse(body);
        resultSet.latitude = coordinates.results[0].geometry.location.lat;
        resultSet.longitude = coordinates.results[0].geometry.location.lng;

        resultSet.localInfo = coordinates.results[0].address_components[0].long_name + ", " +
                    coordinates.results[0].address_components[1].long_name + ", " +
                    coordinates.results[0].address_components[2].long_name + ", " +
                    coordinates.results[0].address_components[3].long_name + ". ";
        resolve(resultSet);
      })
    });

    request.on('error', function(err) {
      reject(err);
    });
  });
}

之后你可以做到

googleRequest(90210).then(function(result) {
    connectToForecastIO(result.latitude, result.longitude);
}

您可以在Promise API docs

中找到有关Promise使用情况的更多信息

您还应该注意,有几个库可用于基于承诺的http请求,例如fetch