jquery 使用 promises 和反向地理编码获取用户位置

jquery get users location using promises and reverse geocoding

  //Get Users Current Location
  $("#collection-search-geolocation").click(function (event) {
          event.preventDefault();
    var zipcode = '';

    getCurrentLocation().then(function(results) {
     console.log('done');
     zipcode = extractZipcode(results);
     callCollectionMap(zipcode);
    });

          return false;
  });

  function extractZipcode(results) {
   var searchAddressComponents = results[0].address_components;
   var zipcode = searchAddressComponents.find(function(el) {
    return el.types[0] == "postal_code";
   }).short_name;
  }
 
  function getCurrentLocation() {
   navigator.geolocation.getCurrentPosition(function (position){
    var geocoder = new google.maps.Geocoder();
    var latLng   = new google.maps.LatLng( 
     position.coords.latitude, position.coords.longitude);
    var deferred = $.Deferred();
     
     geocoder.geocode(
      {'latLng': latLng}
     , function(results, status){
      if (status == google.maps.GeocoderStatus.OK) {
       console.log(results);
       deferred.resolve(results);
      } else {
       deferred.reject(status);
       console.log("Geocode was not successful for the following reason: " + status);
      }
     });

     return deferred.promise();
   });
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="collection-search-geolocation" href="#" class="button collection-point-search-geo-js">Click Here</a>

我正在尝试通过点击获取用户的位置。单击时,我想获取用户的位置,然后在地理编码成功执行后调用一个方法。这是我的代码,但地理编码是异步的,因此我需要使用承诺。

我的问题是 results 在 click 函数中返回 null 因为 geocode.geocoder 还没有完成,但我认为这就是 .done() 应该等到它完成的时候?我也尝试了 .then() 并且结果相同。我收到错误 cannot read 属性 .done() of undefined.

您正在 getCurrentPosition 回调中创建延迟 - 在那里返回它并不意味着它由 getCurrentLocation 返回 - 您需要在 getCurrentPosition 调用之外创建延迟,return deferred.promise() 作为该函数的最后一行,但将 resolve/reject 保留在原处

所以,类似

function getCurrentLocation() {
    var deferred = $.Deferred();
    navigator.geolocation.getCurrentPosition(function(position) {
        var geocoder = new google.maps.Geocoder();
        var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        geocoder.geocode({
            'latLng': latLng
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                console.log(results);
                deferred.resolve(results);
            } else {
                deferred.reject(status);
                console.log("Geocode was not successful for the following reason: " + status);
            }
        });
    });
    return deferred.promise();
}

就个人而言,我会避免使用 jQuery Deferred,因为它不是真正的 Promise/A+ 实现(也许在 3.x 中是这样,但是..)和你用 es6-promise

标记了问题
function getCurrentLocation() {
    return new Promise(function(resolve, reject) {
        navigator.geolocation.getCurrentPosition(function(position) {
            var geocoder = new google.maps.Geocoder();
            var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

            geocoder.geocode({
                'latLng': latLng
            }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    console.log(results);
                    resolve(results);
                } else {
                    reject(status);
                    console.log("Geocode was not successful for the following reason: " + status);
                }
            });
        });
    });
}