Javascript-форум (https://javascript.ru/forum/)
-   Javascript под браузер (https://javascript.ru/forum/css-html/)
-   -   Как сделать функцию асинхронной, если она состоит из нескольких функций в js? (https://javascript.ru/forum/css-html/83365-kak-sdelat-funkciyu-asinkhronnojj-esli-ona-sostoit-iz-neskolkikh-funkcijj-v-js.html)

mav1 23.11.2021 10:13

Как сделать функцию асинхронной, если она состоит из нескольких функций в 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...?

Aetae 23.11.2021 10:32

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

Подробнее...

mav1 23.11.2021 11:26

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

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


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

[object Promice]

voraa 23.11.2021 12:23

Либо
var coords = await addressToCoords('some string with location');
alert(coords)
Либо
addressToCoords('some string with location').then (coords => alert(coords));

Aetae 23.11.2021 12:29

mav1, что делать - в ссылке "подробнее".

mav1 23.11.2021 14:13

Цитата:

Сообщение от voraa (Сообщение 541783)
Либо
var coords = await addressToCoords('some string with location');
alert(coords)

Этот вариант не работает, пишет что await не может быть для async-функции. Ведь до этого в коде указано, что async addressToCoords...

Цитата:

Сообщение от voraa (Сообщение 541783)
addressToCoords('some string with location').then (coords => alert(coords));

А этот не работает, так как "coords" не определено

mav1 23.11.2021 14:22

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

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


Ведь алерт уже выводится после того, как выполнилась addressToCoords(), и, стало быть, result уже должна быть определена. Но увы, не так.

voraa 23.11.2021 15:02

Цитата:

Сообщение от 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?

mav1 23.11.2021 15:59

Пробовал вот в этом примере: 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);
однако его не вижу

voraa 23.11.2021 17:52

А что видите?
В консоле ошибок нет?


Часовой пояс GMT +3, время: 09:54.