根据嵌套函数的条件 'return true' 的最佳方法

Best way to 'return true' based on conditions from nested functions

这可能是一个新手问题,但我正在尝试创建一个 return 为真 的函数。但是,这是基于内部其他几个函数中发生的情况。

function checkGeo(){

    // CHECK FOR GEOLOCATION
    if( "geolocation" in navigator ) {

        navigator.geolocation.getCurrentPosition( function(position){
            sessionStorage.pinlat = position.coords.latitude; 
            sessionStorage.pinlon = position.coords.longitude; 
            // position object is set!
        });

        // position is not defined
        if ( position.coords.latitude && position.coords.longitude ){ 
           return true; 
        }

    }

}

这是我希望我的地理位置检查发生的顺序,但我有点惊讶嵌套的 if 在 getCurrentPosition 方法完成之前被测试。

将此条件放在 getCurrentPosition 成功函数中并从那里 return 为真不会使 checkGeo return 为真。如何检查此异步函数是否已结束并因此检查其结果以便 return true?

匿名函数中的

position 与后面的 if 语句中的 position 不同。 JavaScript 中的范围(为简单起见忽略 ES6 let 关键字)是按功能划分的。

此外,如果 getCurrentPosition() 是异步的,那么您不能先依赖 运行 的匿名回调函数。

如果您只希望 return true 表示您正在尝试获取地理位置信息而不保证一定会成功,请使用更像这样的内容:

function checkGeo(){
    var hasGeolocation = false;

    // CHECK FOR GEOLOCATION
    if( "geolocation" in navigator ) {
        hasGeolocation = true;

        navigator.geolocation.getCurrentPosition( function(position){
            sessionStorage.pinlat = position.coords.latitude; 
            sessionStorage.pinlon = position.coords.longitude; 
            // position object is set! but only inside this function.
        });

        return hasGeolocation;
    }
}

另一方面,如果您试图让 return true 指示地理位置已成功设置,那么您需要用同步函数的 return 值之外的其他方式来指示它,因为在异步函数调用回调之前您不知道它会被设置(可能会发生错误,用户可能不允许对您的站点进行地理定位等)。

地理定位调用是异步的,因此您不能return函数的结果。当函数结束时,您还不知道异步调用的结果。从异步调用的回调中返回任何内容都不会成为函数的 return 值,因为函数已经 returned.

您可以使用回调来报告结果。您必须使用检查异步调用回调中位置的代码:

function checkGeo(callback){
  if( "geolocation" in navigator ) {
    navigator.geolocation.getCurrentPosition(function(position){
      sessionStorage.pinlat = position.coords.latitude; 
      sessionStorage.pinlon = position.coords.longitude; 
      callback(position.coords.latitude && position.coords.longitude);
    });
  } else {
    callback(false);
  }
}

用法:

checkGeo(function(exists){
  // here you can use the result
  if (exists) {
    // ...
  }
});

让你的函数有一个 finished 变量

function checkGeo(){
    var self = this;
    this.ready  = function () {}
    this.result = false;
    if("geolocation" in navigator) {
        navigator.geolocation.getCurrentPosition(function(position) {
            sessionStorage.pinlat = position.coords.latitude; 
            sessionStorage.pinlon = position.coords.longitude; 
            self.result = (position.coords.latitude && position.coords.longitude);
            self.ready.call(self);
        });
    }
}

现在可以使用函数了:

var run = new checkGeo();
run.ready = function () {
    alert(this.result); //Both work
    alert(run.result);  //Both work
};

有点复杂,但我认为编程更好。