2017-05-25 86 views
0

我根據返回值生成不同的返回對象,在lambda函數內部調用REST API端點。我面臨的問題是,當調用http.request()時,它不會觸發正文,最終甚至錯誤方法。使用Nodejs在亞馬遜Lambda內部調用REST API的意外行爲

這裏是我的代碼:

var http = require('http'); 
function getJSON(options, callback){ 

    http.request(options, function(res){ 
     var body = ""; 
     console.log('calling the http'); 
     res.on('body', function(chunk){ 
      console.log('body' + chunk); 
      body+=chunk; 
     }); 
     res.on('end', function(){ 
      console.log('end event');  
      var result = JSON.parse(body); 
      callback(null, result); 
     }) 

     res.on('error', function(error){ 
      console.log('Error event');  
      callback('error', callback); 
     }) 
    }) 
    .on('error', callback) 
    .end();  
} 

function getCityWeather(cityName, outputSessionAttributes){ 

    var options = { 
     host: `api.openweathermap.org`, 
     port: 80, 
     path: `/data/2.5/weather?q=${cityName}&appid=api_key_here`, 
     method: 'GET' 
    }; 

    getJSON(options, function(err, result){ 
     if(err){ 
      console.log(err); 
      return buildValidationResult(false, 'TodayWeatherCity', `Invalid city name. Please let me know the city again.`); 
     } 
     outputSessionAttributes.temprature = result.main.temp; 
     console.log(outputSessionAttributes.temprature + ' value'); 
     return buildValidationResult(true, null, null); 
    }); 

function getWeatherUpdate(intentRequest, callback) { 
    const country = intentRequest.currentIntent.slots.TodayWeatherCountry; 
    const city = intentRequest.currentIntent.slots.TodayWeatherCity; 
    const source = intentRequest.invocationSource; 
    const outputSessionAttributes = intentRequest.sessionAttributes || {}; 

    console.log("outputSessionArribute", intentRequest.sessionAttributes); 

    if (source === 'DialogCodeHook') { 
     const slots = intentRequest.currentIntent.slots; 


     //without promiss implemeation 
     var validationResult = getCityWeather(city, outputSessionAttributes); 
     if(!validationResult.isValid) { 
      console.log('after calling getCityWeather with result'); 
      slots[`${validationResult.violatedSlot}`] = null; 
      //if response not found then return the invalid city message 
      callback(elicitSlot(intentRequest.sessionAttributes, intentRequest.currentIntent.name, slots, validationResult.violatedSlot, validationResult.message)); 
      return; 
     } 
     console.log('getWeatherUpdate after calling getCityWeather'); 
     callback(delegate(outputSessionAttributes, slots)); 
     return; 
    } 

    console.log('getWeatherUpdate after DialogCodeHook'); 
    if(outputSessionAttributes.temprature){ 

     console.log('getWeatherUpdate inside outputSessionAttributes.temprature return'); 
     //get the value from the session variable and prompt to user 
     callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', 
     content: `Okay, temprature reading for ${city} is ${outputSessionAttributes.temprature}` })); 
    } 

    //get the value from the session variable and prompt to user 
    callback(close(outputSessionAttributes, 'Fulfilled', { contentType: 'PlainText', 
    content: `Sorry, I couldn't server your request` })); 
} 

getCityWeather被稱爲它調用getJSON。但一旦打電話getJSON只打印打印http並且函數返回錯誤。

回答

1

此:

res.on('body', ...) 

應該是這樣的:

res.on('data', ...) 

相關信息here

然而,如果'response'事件處理程序被添加,然後從響應該數據必須消費對象,無論何時,只要致電response.read()一個'readable'事件,或者通過添加一個'data'處理程序,或通過調用.resume()方法。在數據消耗完之前,'end'事件不會觸發。此外,在讀取數據之前,它會佔用內存,最終導致「進程內存不足」錯誤。

因此,因爲您沒有添加data處理程序,所以響應流保持暫停狀態。

+0

是的,它應該是res.on('data')而不是res.on('body')謝謝它幫助了我。 – Desmond