Я использую библиотеку node-geocoder в express js, которая имеет следующий код:
var NodeGeocoder = require('node-geocoder');
var options = {
provider: 'google',
// Optional depending on the providers
httpAdapter: 'https', // Default
apiKey: 'YOUR_API_KEY', // for Mapquest, OpenCage, Google Premier
formatter: null // 'gpx', 'string', ...
};
var geocoder = NodeGeocoder(options);
// Using callback
geocoder.geocode('29 champs elysée paris', function(err, res) {
console.info(res);
});
Переменная ответа (res) в функции обратного вызова метода геокодирования содержит объект со свойствами местоположения, такими как широта и долгота. Ссылка на этот пакет: здесь
Мне было интересно, есть ли способ использовать эту переменную ответа вне функции обратного вызова в методе геокодирования. Мне нужно получить свойства широты и долготы, и я не хочу хранить остальную часть кода в этой функции обратного вызова.
Как новичок, я попытался просто вернуть объект и сохранить его в такой переменной:
var object = geocoder.geocode('29 champs elysée paris', function(err, res) {
return res;
});
Это не работает, так как оно находится в обратном вызове и не возвращается в фактическом методе геокодирования.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вы можете использовать ответ своей функции вне обратного вызова, вызвав другую функцию.
geocoder.geocode('29 champs elysée paris', function(err, res) {
if (!err){
// call a function if there is no error
console.info(res);
myFunction();
}
});
function myFunction(){
//do your processing here
}
I don't want to keep the rest of the code within that callback function.
Код не обязательно должен быть в обратным вызовом, его просто нужно назвать из обратным вызовом.
Итак, вы пишете свою функцию (или функции) как обычно:
function handleInfo(info) {
doSomethingWithInfo(info);
doSomethignElse(info);
// ...
}
// ...
... а затем вызовите эти функции, когда у вас есть данные:
geocoder.geocode('29 champs elysée paris', function(err, info) {
if (err) {
// Handle error
} else {
handleInfo(info);
}
});
Не напрямую, но есть несколько способов приблизиться к этому.
Один из них - сделать ваш обратный вызов определенной функцией и использовать ее как обратный вызов:
const doSomething = (err, res) => { /* do something */ }
geocoder.geocode('abc', doSomething);
На самом деле не сильно отличается, но может сделать его немного чище.
Вы также можете «обещать» функцию, чтобы она возвращала Promise. Что-то вроде этого поможет:
const geocodePromise = (path) => new Promise((resolve, reject) => {
geocoder.geocode(path, (err, res) => err ? reject(err) : resolve(res));
});
geocodePromise('abc')
.then(res => { /* do something */ })
.catch(err => { /* do something */ });
Наконец, если вы используете Babel для транспиляции (или Node версии 7.6.0 или выше, у которой он изначально есть), вы можете использовать async и await. Используя ту же обещанную версию функции, что и выше, вам придется заключить свой основной код в функцию async. Обычно для этого я использую анонимную функцию с автоматическим вызовом:
(async () => {
try {
const res = await geocodePromise(path);
/* do something with res */
} catch (err) {
/* do something with err */
}
})();
Таким образом, вы максимально приближаетесь к тому, что хотите, но вам все равно придется заключить основной код в функцию, потому что вы не можете await на верхнем уровне.
geocode уже может вернуть обещание, не нужно его заново оборачивать. Если вас не волнует ошибка и вы просто хотите получить данные о местоположении ответа. Ты можешь сделать это
var locationData = geocoder.geocode('29 champs elysée paris').then( function(res){
return res;
});
Один из способов решить эту проблему - вызвать функцию из обратного вызова. Мой ответ ниже