无法在具有地理位置的 JS Codepen 中的函数之间传递 var API

Can't pass var between functions in JS Codepen with Geolocations API

我在 CodePen 上的 JS 代码中的函数之间传递 url 变量时遇到问题:

var options = {
  enableHighAccuracy: true,
  timeout: 5000,
  maximumAge: 0
};

function success(pos) {
  var crd = pos.coords;
  var lat = crd.latitude;
  var long = crd.longitude;
  var JSONurl = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + long + "&key=MY_APIKEY";

  console.log(JSONurl);
  console.log(`Latitude : ${crd.latitude}`);
  console.log(`Longitude: ${crd.longitude}`);
  return JSONurl;
 };

function error(err) {
  console.warn(`ERROR(${err.code}): ${err.message}`);
};

function getCity() {

  $.getJSON( JSONurl, function( json ) {
  var arr = $.map(json, function(el) { return el; })

  // console.log(Object.keys(arr[3]));
  console.log(arr[3]["address_components"][1]["long_name"]);

  }
)};


var JSONurl = navigator.geolocation.getCurrentPosition(success, error, options);             
getCity(JSONurl);

理想情况下,我只想调用 getCity() 函数,然后该函数调用 success(pos) 函数,然后启动 return JSONurl变量为 getCity().

我不知道为什么这行不通,但它有点老套,所以欢迎提出任何改进建议。

So there are a couple of issues:

  1. navigator.geolocation.getCurrentPosition(success, error, options) does not return a value. So "return JSONurl" will never work.
  2. key=MY_APIKEY should be your googleapis key (https://developers.google.com/maps/documentation/javascript/get-api-key, if not already)
  3. You need to use a promise because you don't know when the googleapis will return the info.
  4. You're probably going to have to use a callback function due to reason above.
  5. You need to take into account if the API denies the request.

Working verison jsfiddle - 将提示输入 google api key

(function(window){

  // Declare internal variables
  var _jsonURL = "";
  var _coords =  "";
  var _latitude =  "";
  var _longitude =  "";

  // Enter your google api key when prompted
  // https://developers.google.com/maps/documentation/javascript/get-api-key
  var APIKEY = prompt("Please enter your google API key ", ""); ; 

  // Create promise
  var _def = $.Deferred();

  window.GoogleAPI = {      
     options : {
                enableHighAccuracy: true,
                timeout: 5000,
                maximumAge: 0
     },
     getGeolocation : function(){
                // Set deferred action
                _def = $.Deferred(navigator.geolocation.getCurrentPosition(success, error, GoogleAPI.options));

                // allows chaining
                return this;
     },
     getCity : function(callback){
        _def.done(function(){
            var city = "";

            $.getJSON( _jsonURL, function( json ) {
               //check if access to the API was denied
               if (json.status == "REQUEST_DENIED"){
                        console.error("API access denied.")
                        callback(null);
                        return;
                    };

               var arr = $.map(json, function(el) { return el; })

               city = arr[3]["address_components"][0]["long_name"];
               console.log(city);

               callback(city);
            })
            .fail(function(){
               console.warn("failed to getCity");              
               callback(null);
            }); //end getJSON          
         }); //end _def

         // allows chaining
         return this;
     } //end getCity
 }; //end window.GoogleAPI 



  function success(pos) {
     _coords = pos.coords;
     _latitude = _coords.latitude;
     _longitude = _coords.longitude;
     _jsonURL = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + _latitude  + "," + _longitude + "&key=" + APIKEY; 

     console.log(_jsonURL);
     console.log(`Latitude : ${_coords.latitude}`);
     console.log(`Longitude: ${_coords.longitude}`);

     // Tell the promise the deferred action has been completed
     _def.resolve();
  };

  function error(err) {
     console.warn(`ERROR(${err.code}): ${err.message}`);

     // Tell the promise the deferred action has failed
     _def.reject();
  };

}(window))

GoogleAPI.getGeolocation()
         .getCity(function(data){
             if(data){
                // do something with the data
                 alert(data);
             }
         });

承诺说明:

Promises/deferred函数是一门沉重的课题。从技术上讲,$.getJSON 是一个假定成功的承诺(尽管它们包括 .fail() 用于错误处理。)

var _def = $.Deferred(navigator.geolocation.getCurrentPosition(success, error, GoogleAPI.options)); <-- create a deferred action (a promise.)

Promise 是异步函数。通常在获取数据有延迟时使用。

_def.resolve(); <-- Says the promised action took place. 
_def.reject(); <-- Says the promised action failed.
_def.done(function(){}) <-- runs if promised action was successful. 
_def.fail(function(){}) <-- runs id promised action failed.