2016-09-10 4 views
0

Я хочу вернуть значение в основную часть моей функции AWS. У меня возникли проблемы с передачей данных от первого обратного вызова, поэтому я могу отправить его в последний.Обратный вызов AWS в обратном вызове

/** module used for outbound http requests */ 
    var request = require('request'); 

    /** module used for parsing XML easily. https://www.npmjs.com/package/xml2js*/ 
    var parseString = require('xml2js').parseString; 
exports.handler = (event, context, callback) => { 

    // testing array of coordinates 
    var arrayOfPoints = [39.7683800, -86.1580400, 41.881832, -87.623177]; 
    var results = getXMLFromNOAA(arrayOfPoints); 
    callback(null, results); // <- returns 'undefined' in the AWS console. I'm assuming race condition. 
}; 

/** 
* getXMLFromNOAA 
* 
* This is a function used for figuring out the functionality of NOAA XML parsing 
* 
* @param arrayOfPoints {Array[Double]} - An evenly numbered index array of latitudes and longitudes 
* 
* @return result {XML/JSON} - weather information abled to be parsed 
*/ 
function getXMLFromNOAA(arrayOfPoints, callback) { 

    var baseURL = "http://graphical.weather.gov/xml/sample_products/browser_interface/ndfdXMLclient.php?whichClient=NDFDgenLatLonList&lat=&lon=&listLatLon="; 

    // for-loop getting all points and dynamically adding them to the query url string 
    // iterate 2 at a time since they are coupled coordinates (e.g. [lat1, lng1, lat2, lng2, ... latN, lngN]) 
    for(var i = 0; i < arrayOfPoints.length; i = i + 2) 
    { 
     // if we're at the end of the arrayOfPoints, finish up the chain of query coordinates 
     if((i+2) == arrayOfPoints.length) 
     { 
      baseURL = baseURL.concat(arrayOfPoints[i]); 
      baseURL = baseURL.concat("%2C"); 
      baseURL = baseURL.concat(arrayOfPoints[i+1]); 
     } 
     else 
     { 
      baseURL = baseURL.concat(arrayOfPoints[i]); 
      baseURL = baseURL.concat("%2C"); 
      baseURL = baseURL.concat(arrayOfPoints[i+1]); 
      baseURL = baseURL.concat("+"); 
     } 
    } 

    // TIME 
    baseURL = baseURL.concat("&lat1=&lon1=&lat2=&lon2=&resolutionSub=&listLat1=&listLon1=&listLat2=&listLon2=&resolutionList=&endPoint1Lat=&endPoint1Lon=&endPoint2Lat=&endPoint2Lon=&listEndPoint1Lat=&listEndPoint1Lon=&listEndPoint2Lat=&listEndPoint2Lon=&zipCodeList=&listZipCodeList=&centerPointLat=&centerPointLon=&distanceLat=&distanceLon=&resolutionSquare=&listCenterPointLat=&listCenterPointLon=&listDistanceLat=&listDistanceLon=&listResolutionSquare=&citiesLevel=&listCitiesLevel=&sector=&gmlListLatLon=&featureType=&requestedTime=&startTime=&endTime=&compType=&propertyName=&product=time-series&begin=2016-09-04T00:00:00&end=2016-09-11T00:00:00"); 

    // CHARACTERISTICS REQUESTED 
    // http://graphical.weather.gov/xml/docs/elementInputNames.php 
    baseURL = baseURL.concat("&Unit=e&maxt=maxt&mint=mint&temp=temp&appt=appt&rh=rh&sky=sky&wwa=wwa&iceaccum=iceaccum&ptornado=ptornado&phail=phail&ptstmwinds=ptstmwinds&pxtornado=pxtornado&pxhail=pxhail&ptotsvrtstm=ptotsvrtstm&wgust=wgust"); 

    // Used for testing and seeing the final result 
    console.log(baseURL); 

    request(baseURL, function (error, response, body) 
    { 
     if (!error && response.statusCode == 200) 
     { 
      parseString(body, function (err, result) { 
       console.log('inside parseString: ' + result); // <- this prints but it won't show up in the main 
       // callback(null, result); <- doesnt work 
       return result; // doesnt work either 
      }); 
     } 
    }) 
} 

Я хочу, чтобы мой код был более модульным для масштабируемости. Я знаю, что это способ принять асинхронный процесс getXMlFromNOAA и выполнить их итеративно. Я просто не так хорошо знаком с JavaScript, каким должен быть. Любая помощь будет действительно оценена.

ответ

2

Вы можете использовать async module, чтобы сделать его более читабельным и гибким, а также без асинхронной проблемы. Написать свой материал что-то вроде этого

/** module used for outbound http requests */ 
var request = require('request'); 
var async = require('async'); 

/** module used for parsing XML easily. https://www.npmjs.com/package/xml2js*/ 
var parseString = require('xml2js').parseString; 
exports.handler = (event, context, callback) => { 

    async.waterfall([ 

     function(next) { 
      // testing array of coordinates 
      var arrayOfPoints = [39.7683800, -86.1580400, 41.881832, -87.623177]; 
      var results = getXMLFromNOAA(arrayOfPoints, next); 

     }, 
     function(baseURL, next) { 

      request(baseURL, function(error, response, body) { 
       if (!error && response.statusCode == 200) { 
        parseString(body, function(err, result) { 
         console.log('inside parseString: ' + result); // <- this prints but it won't show up in the main 
         if (!err) 
          next(null, result); 
        }); 
       } 
      }) 

     } 
    ], function(err, result) { 
     if (!err) { 
      callback(null, results); // <- returns 'undefined' in the AWS console. I'm assuming race condition. 
     } 

    }) 

}; 

/** 
* getXMLFromNOAA 
* 
* This is a function used for figuring out the functionality of NOAA XML parsing 
* 
* @param arrayOfPoints {Array[Double]} - An evenly numbered index array of latitudes and longitudes 
* 
* @return result {XML/JSON} - weather information abled to be parsed 
*/ 
function getXMLFromNOAA(arrayOfPoints, next) { 

    var baseURL = "http://graphical.weather.gov/xml/sample_products/browser_interface/ndfdXMLclient.php?whichClient=NDFDgenLatLonList&lat=&lon=&listLatLon="; 

    // for-loop getting all points and dynamically adding them to the query url string 
    // iterate 2 at a time since they are coupled coordinates (e.g. [lat1, lng1, lat2, lng2, ... latN, lngN]) 
    for (var i = 0; i < arrayOfPoints.length; i = i + 2) { 
     // if we're at the end of the arrayOfPoints, finish up the chain of query coordinates 
     if ((i + 2) == arrayOfPoints.length) { 
      baseURL = baseURL.concat(arrayOfPoints[i]); 
      baseURL = baseURL.concat("%2C"); 
      baseURL = baseURL.concat(arrayOfPoints[i + 1]); 
     } else { 
      baseURL = baseURL.concat(arrayOfPoints[i]); 
      baseURL = baseURL.concat("%2C"); 
      baseURL = baseURL.concat(arrayOfPoints[i + 1]); 
      baseURL = baseURL.concat("+"); 
     } 
    } 

    // TIME 
    baseURL = baseURL.concat("&lat1=&lon1=&lat2=&lon2=&resolutionSub=&listLat1=&listLon1=&listLat2=&listLon2=&resolutionList=&endPoint1Lat=&endPoint1Lon=&endPoint2Lat=&endPoint2Lon=&listEndPoint1Lat=&listEndPoint1Lon=&listEndPoint2Lat=&listEndPoint2Lon=&zipCodeList=&listZipCodeList=&centerPointLat=&centerPointLon=&distanceLat=&distanceLon=&resolutionSquare=&listCenterPointLat=&listCenterPointLon=&listDistanceLat=&listDistanceLon=&listResolutionSquare=&citiesLevel=&listCitiesLevel=&sector=&gmlListLatLon=&featureType=&requestedTime=&startTime=&endTime=&compType=&propertyName=&product=time-series&begin=2016-09-04T00:00:00&end=2016-09-11T00:00:00"); 

    // CHARACTERISTICS REQUESTED 
    // http://graphical.weather.gov/xml/docs/elementInputNames.php 
    baseURL = baseURL.concat("&Unit=e&maxt=maxt&mint=mint&temp=temp&appt=appt&rh=rh&sky=sky&wwa=wwa&iceaccum=iceaccum&ptornado=ptornado&phail=phail&ptstmwinds=ptstmwinds&pxtornado=pxtornado&pxhail=pxhail&ptotsvrtstm=ptotsvrtstm&wgust=wgust"); 

    // Used for testing and seeing the final result 
    console.log(baseURL); 
    //retun to callback after getting URL 
    next(null, baseURL) 
} 
+0

Прекрасно работает, большое спасибо – booky99

+0

Пожалуйста, не забывайте upvote :) – abdulbarik

0

Thats не так, как обратные вызовы работают. Изменение обработчика на что-то вроде этого:

exports.handler = (event, context, callback) => { 
    var arrayOfPoints = [39.7683800, -86.1580400, 41.881832, -87.623177]; 
    getXMLFromNOAA(arrayOfPoints, function(result) { 
    console.log('returned'); 
    console.log(result); 
    callback(null, result); 
    }); 
}; 

Также раскомментировать (вернуться) к callback(result) в getXMLFromNOAA;

Также для NOAA имеется модуль. Всегда сначала найдите узловые модули/npmjs.com/npms.io, прежде чем изобретать колесо. Пример здесь https://github.com/thataustin/noaa-forecasts очень похож на то, что вы делаете, поэтому я начну с этого.

Если вы хотите упростить асинхронный материал в будущем, вы можете использовать babel с async и await ключевыми словами. Но сначала вам нужно убедиться, что вы действительно изучаете обратные вызовы и обещания.

Смежные вопросы