2014-12-17 3 views
1

Я пытаюсь научиться Node.jsСоздание обратного вызова возвращает массив из функции

У меня возникают проблемы при создании моего собственного обратного вызова на функции. Это похоже на такую ​​простую вещь, но я не совсем понимаю, как это сделать.

Функция передается по адресу (пример: «1234 будет ln, co»), который использует google geolocate json api для возврата полного адреса, широты и долготы в массиве.

Вот мой код:

//require secure http module 
var https = require("https"); 

//My google API key 
var googleApiKey = "my_private_api_key"; 

//error function 
function printError(error) { 
    console.error(error.message); 
} 

function locate(address) { 
//accept an address as an argument to geolocate 

    //replace spaces in the address string with + charectors to make string browser compatiable 
    address = address.split(' ').join('+'); 

    //var geolocate is the url to get our json object from google's geolocate api 
    var geolocate = "https://maps.googleapis.com/maps/api/geocode/json?key="; 
    geolocate += googleApiKey + "&address=" + address; 

    var reqeust = https.get(geolocate, function (response){ 

     //create empty variable to store response stream 
     var responsestream = ""; 

     response.on('data', function (chunk){ 
      responsestream += chunk; 
     }); //end response on data 

     response.on('end', function(){ 
      if (response.statusCode === 200){ 
       try { 
        var location = JSON.parse(responsestream); 
        var fullLocation = { 
         "address" : location.results[0].formatted_address, 
         "cord" : location.results[0].geometry.location.lat + "," + location.results[0].geometry.location.lng 
        }; 
        return fullLocation; 
       } catch(error) { 
        printError(error); 
       } 
      } else { 
       printError({ message: "There was an error with Google's Geolocate. Please contact system administrator"}); 
      } 
     }); //end response on end 

    }); //end https get request 

} //end locate function 

Так что, когда я пытаюсь выполнить мою функцию

var testing = locate("7678 old spec rd"); 
console.dir(testing); 

журналов консолей не определен, потому что его не ждет возвращения из локализации (или, по крайней мере, я угадать, что это проблема).

Как создать обратный вызов, поэтому, когда функция locate возвращает мой массив, она запускает console.dir в возвращаемом массиве.

Спасибо! Надеюсь, мой вопрос имеет смысл, я сам преподаю, поэтому мой технический жаргон ужасен.

+0

Добро пожаловать в асинхронном мире! Если ваша функция включает обратные вызовы, вы не можете «вернуть» что-либо из нее. Вы должны использовать другой обратный вызов или библиотеку обещаний. – georg

+0

Взгляните на объяснение обратных вызовов в статье [Искусство узла] (https://github.com/maxogden/art-of-node#callbacks). Это поможет вам понять, как справляться с этими ситуациями. –

+0

Спасибо за информацию. Я обязательно проверю эти другие статьи. – magreenberg

ответ

3

Вам необходимо пройти в функции обратного вызова в ваш метод - так что обратный вызов может выглядеть как этот

function logResult(fullLocation){ 
    console.log(fullLocation) 
} 

Вы бы передать это в ваш метод locate наряду с входом:

// note: no parentheses, you're passing a reference to the method itself, 
// not executing the method 
locate("1234 will ln, co",logResult) 

вы также можете сделать это инлайн - так же, как response объекта вы уже дело с:

locate("1234 will ln, co",function(fullLocation){ 
    // do something useful here 
}) 

Теперь для бита внутри вашего метода, вместо того, чтобы пытаться return результат вы просто вызовите функцию обратного вызова в результате:

function locate(address, callback) { 
    ...... 

    response.on('end', function(){ 
     if (response.statusCode === 200){ 
      try { 
       var location = JSON.parse(responsestream); 
       var fullLocation = { 
        "address" : location.results[0].formatted_address, 
        "cord" : location.results[0].geometry.location.lat + "," + location.results[0].geometry.location.lng 
       }; 
       callback(fullLocation); // <-- here!!! 
      } catch(error) { 
       printError(error); 
      } 
     } else { 
      printError({ message: "There was an error with Google's Geolocate. Please contact system administrator"}); 
     } 
    }); //end response on end 

    ..... 
} 
+0

Большое вам спасибо за быстрый ответ! :) Это сработало отлично. – magreenberg

+0

@magnetwd - не проблема, вам также может понравиться прочитать связанный дубликат, у него есть действительно полезная информация, если вы новичок в этом асинхронном javascript. – Jamiec

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