Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 23.11.2021, 10:13
Аватар для mav1
Аспирант
Отправить личное сообщение для mav1 Посмотреть профиль Найти все сообщения от mav1
 
Регистрация: 30.08.2010
Сообщений: 57

Как сделать функцию асинхронной, если она состоит из нескольких функций в js?
У меня есть подобная функция:

function addressToCoords(local) {
    var address = local;
    var result = '';
    geocoder.geocode( { 'address': address}, function(results, status) {
        
      if (status == 'OK') {
         result = results[0].geometry.location;
      } else {
        console.log('Error: ' + status);
         result = '';
      }
        alert('Result is '+result);
    });
        
    alert('Result2 is '+result);
    return result;
  }


Так как для выполнения геокодирования необходимо некоторое время, сначала выводится сообщение "Result2 is ", и только после этого сообщение "Result is {координаты}" , ну и функция возвращает пустышку вместо {координат}. Как я понимаю, я должен сделать так, чтобы функции выполнялись асинхронно. Вижу в документации js на сайте мозиллы подобный пример:

async function f() {
  return 1;
}
f().then(alert);


Но как быть в моем случае с geocoder.geocode...?
Ответить с цитированием
  #2 (permalink)  
Старый 23.11.2021, 10:32
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

function asyncGeocode(params) {
  return new Promise((resolve, reject) => geocoder.geocode(
    params, 
    (results, status) => status === 'OK' ? resolve(results) : reject(status)
  ));
}

async function addressToCoords(local) {
  var address = local;
  var result = await asyncGeocode({address}).catch(status => {
    console.log('Error: ' + status);
    return '';
  });

  alert('Result is ' + result);
  return result;
}

Подробнее...
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 23.11.2021, 11:26
Аватар для mav1
Аспирант
Отправить личное сообщение для mav1 Посмотреть профиль Найти все сообщения от mav1
 
Регистрация: 30.08.2010
Сообщений: 57

Пример, приведенный вами, видимо рабочий, однако что делать с результатом выполнения функции addressToCoords(), если :

var coords = addressToCoords('some string with location');
alert(coords);


показывает мне:

[object Promice]

Последний раз редактировалось mav1, 23.11.2021 в 11:30.
Ответить с цитированием
  #4 (permalink)  
Старый 23.11.2021, 12:23
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Либо
var coords = await addressToCoords('some string with location');
alert(coords)
Либо
addressToCoords('some string with location').then (coords => alert(coords));
Ответить с цитированием
  #5 (permalink)  
Старый 23.11.2021, 12:29
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,480

mav1, что делать - в ссылке "подробнее".
__________________
29375, 35
Ответить с цитированием
  #6 (permalink)  
Старый 23.11.2021, 14:13
Аватар для mav1
Аспирант
Отправить личное сообщение для mav1 Посмотреть профиль Найти все сообщения от mav1
 
Регистрация: 30.08.2010
Сообщений: 57

Сообщение от voraa Посмотреть сообщение
Либо
var coords = await addressToCoords('some string with location');
alert(coords)
Этот вариант не работает, пишет что await не может быть для async-функции. Ведь до этого в коде указано, что async addressToCoords...

Сообщение от voraa Посмотреть сообщение
addressToCoords('some string with location').then (coords => alert(coords));
А этот не работает, так как "coords" не определено
Ответить с цитированием
  #7 (permalink)  
Старый 23.11.2021, 14:22
Аватар для mav1
Аспирант
Отправить личное сообщение для mav1 Посмотреть профиль Найти все сообщения от mav1
 
Регистрация: 30.08.2010
Сообщений: 57

Вроде бы должно быть что-то наподобие (судя по примерам с ссылки "подробнее"):

addressToCoords('some string with location').then(alert(result));


Ведь алерт уже выводится после того, как выполнилась addressToCoords(), и, стало быть, result уже должна быть определена. Но увы, не так.
Ответить с цитированием
  #8 (permalink)  
Старый 23.11.2021, 15:02
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

Сообщение от mav1
Этот вариант не работает, пишет что await не может быть для async-функции. Ведь до этого в коде указано, что async addressToCoords...
Вы наверно читать не умеете.
Там скорее всего написано, что await может быть ТОЛЬКО в async функциях.
Это действительно так. Поэтому функция, где используется await, тоже должна быть объявлена, как async.
Если такой функции нет (код исполняется на верхнем уровне скрипта), то приходится делать фиктивную функцию и тут же ее вызывать
[QUOTE=mav1]Сообщение от voraa 
addressToCoords('some string with location').then (coords => alert(coords));
А этот не работает, так как "coords" не определено[/QUOTE]


Вы сами пробовали, что не работает?
зачем определять coords, если это формальный параметр фунции передаваемой в then?
Ответить с цитированием
  #9 (permalink)  
Старый 23.11.2021, 15:59
Аватар для mav1
Аспирант
Отправить личное сообщение для mav1 Посмотреть профиль Найти все сообщения от mav1
 
Регистрация: 30.08.2010
Сообщений: 57

Пробовал вот в этом примере: http://95.174.111.242:8091/maptest/test.php

Полный код данной тестовой странички:

<html>
<head>
<title>Geocode example</title>
</head>
<body>
<p>map</p>
<style>
html,
body,
#map_canvas {
  height: 100%;
  width: 100%;
  margin: 0px;
  padding: 0px
}
</style>

<script src="https://maps.googleapis.com/maps/api/js?key=key"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>

<script>
	


var geocoder;
var map;
var bounds = new google.maps.LatLngBounds();

function initialize() {
	geocoder = new google.maps.Geocoder();
  map = new google.maps.Map(
    document.getElementById("map_canvas"), {
      center: new google.maps.LatLng(41.92233950111221, 12.442120355172237),
      zoom: 13,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });

  
}
	
initialize();
	
	function asyncGeocode(params) {
		alert('asyncGeocode started with params: '+params);
  return new Promise((resolve, reject) => geocoder.geocode(
    params, 
    (results, status) => status === 'OK' ? resolve(results) : reject(status)
  ));
}

async function addressToCoords(loc) {
  var address = loc;
  var result = await asyncGeocode(address).catch(status => {
    console.log('Error: ' + status);
    return '';
  });
  alert('now here');
  alert('Result is ' + result);
  return result;
}

	addressToCoords('Rome, Italy').then (coords => alert(coords));
	alert(result);
	
	
</script>
</body>
</html>


Должен сработать
alert('Result is ' + result);
однако его не вижу

Последний раз редактировалось mav1, 25.11.2021 в 12:47.
Ответить с цитированием
  #10 (permalink)  
Старый 23.11.2021, 17:52
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,692

А что видите?
В консоле ошибок нет?
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать обратную функцию в моём случае? DobrovolskyDen Общие вопросы Javascript 14 08.05.2018 09:16
Как сделать одну функцию из двух? MyNameIsCode AJAX и COMET 4 05.05.2017 09:52
Как сделать выполнение одного JS после выполнения другого vita1ii Events/DOM/Window 2 11.01.2013 18:52
Подскажите как сделать меню на CSS если: greatilya (X)HTML/CSS 10 18.10.2009 20:26
js файл(незнаю как запустить функцию) Temchik Opera, Safari и др. 6 20.07.2009 11:49