2016-07-26 32 views
0

我想教自己nodejs和expressjs,然而來自java和C++這證明很難習慣。如何在nodejs中管理依賴函數

我做了一個簡單而雜亂的模塊,它應該返回給定郵政編碼的天氣預報。

發生這種情況的方式是通過獲取用戶郵政編碼並使用Google API生成該郵政編碼的地理座標。我從JASON文件中獲取座標,然後將它們提供給下一個api調用,此調用將完成到forecast.io api,並且此位置的天氣數據也將從JASON文件中獲取。

來自java和JavaScript上不那麼紮實的背景我很難讓這兩個函數等待另一個,在這種情況下,我需要谷歌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; 

是return語句妥善安置?我最終在這裏使用了嗎?請注意,我來自java背景,在java中使用try {} catch(){}和finally {}塊來執行閉包代碼是完全正確的,這是我管理此模塊的唯一方法。但是現在我已經整合了一些Express,並且我嘗試從另一個模塊執行這個模塊的方法,我得到的只是一個未定義的返回。

回答

0

你可以使用無極API,有點像在Java的期貨,所以基本上你可以做的是包裹在承諾這兩個函數和,你可以等待的決心,執行下一個功能

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

用法你還應該注意,有幾個庫允許基於承諾的http請求,如fetch