#javascript #.net #google-maps #async-await
#язык JavaScript #.net #google-карты #асинхронное ожидание
Вопрос:
отредактированный:
Получение координат и расстояний с помощью Google Maps API. Работает нормально, но когда я пытаюсь отправить эти данные на свой контроллер с помощью Ajax, эти данные равны нулю.
Итак, я начал использовать функцию ожидания/асинхронности. После этого и некоторых подсказок я получаю все данные от Google, но все равно получаю нулевые данные на своем контроллере (Lat, Lng и расстояние). Другие значения из моих входных данных в порядке.
Мой код JavasScript:
$("#btnConfirm").click(async function (e) { e.preventDefault(); var _this = $(this); var _form = _this.closest("form"); var isvalid = _form.valid(); if (isvalid) { await GetLatLngGoogle($('#address').val()); ^^^^ await GetDistance(); ^^^^ AddAddress(); } }); async function GetLatLngGoogle(address) { return new Promise((resolve) =gt; { geocoder = new google.maps.Geocoder(); geocoder.geocode({ 'address': address }, function (results, status) { $("#Lat").val(results[0].geometry.location.lat()); $("#Lng").val(results[0].geometry.location.lng()); }); resolve('resolved'); }); }; var map = null; var start = null; var end = null; var directionsService = null; var directionsDisplay = null; async function GetDistance() { return new Promise((resolve) =gt; { var center = new google.maps.LatLng(40.71620968890981, -74.08542546242037); var clientPosition = new google.maps.LatLng(40.70550895916085, -74.0791867502397); var storePosition = { lat: 40.71620968890981, lng: -74.08542546242037 }; directionsService = new google.maps.DirectionsService(); directionsDisplay = new google.maps.DirectionsRenderer(); var route = { origin: storePosition , destination: clientPosition, travelMode: google.maps.TravelMode.DRIVING }; directionsService.route(route, RenderCustomDirections); resolve('resolved'); }); }; async function RenderCustomDirections(response, status) { if (status == google.maps.DirectionsStatus.OK) { start = new Object(); end = new Object(); var legs = response.routes[0].legs; for (i = 0; i lt; legs.length; i ) { if (i == 0) { start.latlng = legs[i].start_location; start.address = legs[i].start_address; } end.latlng = legs[i].end_location; end.address = legs[i].end_address; } directionsDisplay.setDirections(response); computeTotalDistance(directionsDisplay.getDirections()); } else alert(status); }; async function computeTotalDistance(result) { let total = 0; let timeTotal = 0; const myroute = result.routes[0]; if (!myroute) { return; } for (let i = 0; i lt; myroute.legs.length; i ) { total = myroute.legs[i].distance.value; timeTotal = myroute.legs[i].duration.value; } total = total / 1000; timeTotal = timeTotal / 60; $('#Distance').val(total.toFixed(1)); }; function AddAddress() { var options = {}; options.type = "POST"; options.url = "/api/AddAddress"; options.dataType = "JSON"; options.cache = false; options.async = true; contentType = "application/json; charset=utf-8", options.data = $('#formAdd').serialize(); options.beforeSend = function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); }; options.success = function (data) { }; options.error = function () { }; $.ajax(options); };
Мой Html:
lt;form id="formAdd"gt; lt;button class="btn btn-info btn-sm" id="btnConfirm"gt; Confirm lt;/buttongt; ... lt;input asp-for="Lat" value="@Model.Lat" type="hidden" /gt; lt;input asp-for="Lng" value="@Model.Lng" type="hidden" /gt; lt;input asp-for="Distance" value="@Model.Distance" type="hidden" /gt; lt;/formgt; lt;script async defer src="https://maps.googleapis.com/maps/api/js?key=xxxxxx"gt;lt;/scriptgt; lt;script src="~/js/app/addressAddAddress.min.js"gt;lt;/scriptgt;
Комментарии:
1.
await GetLatLngGoogle($('#address').val()); // working fine
Вы никогда не выполняете обещаниеGetLatLngGoogle
. Следовательно, именно поэтому остальная часть кода не работает, потомуawait
что значение ed никогда не разрешится. У вас та же проблемаGetDistance()
— обещание никогда не будет выполнено.2. Небольшой совет!!, Старайтесь избегать шаблона конструктора обещаний для общего использования. Напр.. Если, скажем, сторонняя библиотека имеет только обратные вызовы и не использует обещания (я удивлен, если google Api уже не использует их). Я бы создал функцию-оболочку для обратного вызова, и тогда это позволит избежать того, чтобы шаблон конструктора обещаний засорял вашу кодовую базу. IOW:
new Promise(...)
должно быть, это редкая вещь, которую можно увидеть в любой кодовой базе.3. Как это решить? Мне нужно передать возвращаемое значение? @ВЛАЗ
4. Не создавайте экземпляр своей карты в функции getDistance. Это приведет к взиманию платы за каждый вызов артикула динамических карт.
5. Когда я помещаю setTimeout() внутри каждой функции, она работает нормально. setTimeout (() = gt; { разрешить(«решено»); }, 3000);. Но я не хочу, чтобы пользователь устанавливал время ожидания.