回调中的空数组

时间:2017-07-29 13:16:37

标签: javascript node.js

我正在使用地理编码器npm模块将地址转换为lat,long。 此API在结果之后使用快速google.csv模块从文件csv npm读取地址,即地址分别传递给getLatLong函数以转换为纬度和经度。现在,当我通过latlongArray时在getLatLong回调中,它变为空。这是因为范围而得到的。建议。

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);
}

2 个答案:

答案 0 :(得分: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);
            }
        })
    }); 
}

答案 1 :(得分: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来执行它们。一旦完成所有这些操作,将调用包含所有执行结果的回调。