2017-07-29 10 views
0

私はジオコーダーのnpmモジュールを使用してアドレスをlat、longに変換しています。 このAPIは、緯度と経度は、それぞれ、私はそれがempty.Thisが原因scope.Kindlyで取得されて行くlatlongArraygetLatLongコールバックに渡すとき.Nowに変換すること、すなわちアドレスがgetLatLong関数に渡され、その結果後に高速csv npmモジュールを使用してファイルgoogle.csvからアドレスを読み出します提案する。コールバックの配列が空です

const geocoder = require('geocoder'); 
const json2csv = require('json2csv'); 
const fs   = require('fs'); 
const csv  = require('fast-csv'); 
var stream  = fs.createReadStream("google.csv"); 
var path   = './google.csv'; 
var async  = require('async'); 
var responseObj = {}; 
var latlongArray = []; 

var asyncArray =[getCsvdata.bind(null, path, responseObj), 
        getLatLong.bind(null, responseObj)]; 
async.series(asyncArray ,function(err, result){ 
    if(err){ 
     console.log(err); 
     return err; 
    } 
    console.log(JSON.stringify(result)); 
}) 

function getCsvdata(path, responseObj, callback){ 
    var SuccessArray = []; 
    var ErrorArray = []; 
    csv.fromPath(path) 
     .on('data', function (data) { 
      SuccessArray.push(data); 
     }) 
     .on("error", function (data) { 
      ErrorArray.push(data); 
     }) 
     .on('end', function() { 
      var ResultObject   = {Success: SuccessArray, ErrorList: ErrorArray}; 
      responseObj.adrressarray = ResultObject; 
      callback(null, ResultObject); 
     }); 
} 
function getLatLong(responseObj, callback){ 
    var responseArray = responseObj.adrressarray; 
    var geocodeArray = responseArray.Success.slice(1); 
    var geoLatLong = geocodeArray.map(function(x) { 
      var addressOfRow = x.toString(); 
      geocoder.geocode(addressOfRow, function (err, data) { 
      if(err){ 
       return callback(err); 
      } 
      var latitude = data.results[0].geometry.location.lat; 
      var longitude = data.results[0].geometry.location.lng; 
      var address  = data.results[0].formatted_address; 
      var obj   = [{"latitude":latitude,"longitude":longitude, "address":address}]; 
      latlongArray.push(obj); 
     }) 
    }); 

    return callback(null, latlongArray); 
} 
+0

これは、非同期関数のコールバックを使用してその変数にデータを格納しているため、コードを実行する前にコールバックが発生したために発生します。 – Salketer

+0

これは本当です@Salketer – art12345

答えて

1

あなたはasync.parallelを使いたいでしょう:

は、これらの変更を行います。複数のgeocoder.geocodeを呼び出しているためです。非同期なので、関数は終了する前に値を返します。

function getLatLong(responseObj, callback){ 
    var responseArray = responseObj.adrressarray; 
    var geocodeArray = responseArray.Success.slice(1); 
    var geoLatLongFunctions = geocodeArray.map(function(x) { 
     return function(cb){ 
      var addressOfRow = x.toString(); 
      geocoder.geocode(addressOfRow, function (err, data) { 
       if(err){ 
        cb(err); 
       } 
       var latitude = data.results[0].geometry.location.lat; 
       var longitude = data.results[0].geometry.location.lng; 
       var address  = data.results[0].formatted_address; 
       var obj   = [{"latitude":latitude,"longitude":longitude, "address":address}]; 
       cb(null,obj); 
      }); 
     }; 
    }); 
    async.parallel(geoLatLongFunctions,callback); 
} 

ここでは、geocodeArray.mapが関数を返すようにしています。 async.parallelを使ってそれらを実行しました。すべてが終了すると、すべての実行結果を含むコールバックが呼び出されます。

+0

getLatLongが最終的にasync.seriesに戻った方法を教えてください。 @Salketer – art12345

+0

['async.parallel'](https://caolan.github.io/async/docs.html#parallel)のドキュメントを参照してください:*"タスクが完了すると、結果は次のように最終コールバックに渡されます。アレイ。 "* – trincot

1

コールバックがあまりにもすぐに(同期的に)呼び出されますが、配列はあとで(非同期に)読み込まれるだけです。

function getLatLong(responseObj, callback){ 
    var latlongArray = []; // Define & initialise array here! 
    var responseArray = responseObj.adrressarray; 
    var geocodeArray = responseArray.Success.slice(1); 
    geocodeArray.map(function(x) { 
     var addressOfRow = x.toString(); 
     geocoder.geocode(addressOfRow, function (err, data) { 
      if(err){ 
       return callback(err); 
      } 
      var latitude = data.results[0].geometry.location.lat; 
      var longitude = data.results[0].geometry.location.lng; 
      var address  = data.results[0].formatted_address; 
      var obj   = [{"latitude":latitude,"longitude":longitude, "address":address}]; 
      latlongArray.push(obj); 
      // Only call callback when array is complete 
      if (latlongArray.length == geocodeArray.length) { 
       callback(null, latlongArray); 
      } 
     }) 
    }); 
} 
+0

あなたはgetLatLongが最後にasync.series?@trincotに返された方法を教えてください@Salketerの上記の答えで – art12345

+0

私はここが正しいと思いますよね?私は他の答えにコメントを追加しました。 – trincot

+0

"タスクが完了すると、結果は配列として最終コールバックに渡されますが、タスクはジオコードであり、結果はasync.parallel最終コールバックに渡されます。このジオコード関数からコールバックはありません(err、result)async.series @trincotに到達する方法 – art12345

関連する問題