【问题标题】:How can I use a deferred object to retrieve a longitude and latitude with the HTML5 Geolocation API?如何使用延迟对象通过 HTML5 Geolocation API 检索经度和纬度?
【发布时间】:2014-11-15 20:46:18
【问题描述】:

我想使用 HTML5 GeoLocation API 来检索我的经度和纬度,并使用 jQuery Deferred 对象管理请求。

我的代码如下所示:

var geoLocation = {

    getLocation: function() {

        // create deferred object
        var deferred = $.Deferred();

        // if geo location is supported
        if(navigator.geolocation) {

            // get current position and pass the results to this.geoLocationSuccess or time out after 5 seconds if it fails
            navigator.geolocation.getCurrentPosition(this.geoLocationSuccess, this.geoLocationError, {
                timeout: 5000
            });

        } else {

            // geo location isn't supported
            console.log('Your browser does not support Geo Location.');
        }

    },

    geoLocationSuccess: function(position) {

        // resolve deffered object
        deferred.resolve(position.coords.latitude, position.coords.longitude);

        // return promise
        return deferred.promise();
    },

    geoLocationError: function() {
        console.log('Geo Location failed.');
    }

};

这是我的 Deferred 对象:

$.when(geoLocation.getLocation()).then(function(data, textStatus, jqXHR) {

    console.log(data);

});

我希望then() 回调返回经度和纬度,但我得到deferred 未定义的错误。我认为这与我定义延迟对象的范围有关,但我不确定。我错过了什么?

【问题讨论】:

    标签: jquery geolocation promise deferred


    【解决方案1】:

    Michael,在阅读了 Hackaholic 的回答和您自己的回答后,两者都可以处理成功返回的数据,但可以更好地处理错误。

    如果navigator.geolocation.getCurrentPosition() 失败,它会将一个可能提供信息的PositionError 对象传递给它的错误处理程序。这个对象,它可以被传递到承诺链并在调用函数中处理,在两个答案中都被忽略了。

    同样,promise 拒绝也可用于将您自己的“您的浏览器不支持 Geo Location”错误传递到 Promise 链中。

    var geoLocation = {
        getLocation: function() {
            var deferred = $.Deferred();
            if(navigator.geolocation) {
                // geo location is supported. Call navigator.geolocation.getCurrentPosition and :
                // - resolve the promise with the returned Position object, or
                // - reject the promise with the returned PositionError object, or
                // - time out after 5 seconds
                navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, { timeout: 5000 });
            } else {
                //geo location isn't supported
                //Reject the promise with a suitable error message
                deferred.reject(new Error('Your browser does not support Geo Location.'));
            }
            return deferred.promise();
        } 
    };
    

    忽略 cmets,这是非常紧凑的,请注意 geoLocation.getLocation() 如何不尝试处理错误,而是将它们提供给调用函数的错误处理程序。

    现在,$.when() 不是必需的,因为您的 geoLocation.getLocation() 函数返回一个具有自己的 .then() 方法的承诺。没有$.when(),它已经是“thenable”了。

    geoLocation.getLocation().then(function(position) {
        console.dir(position);
    }).fail(function(err) {
        console.error(err);
    });
    

    因此,您充分利用了 Promise 处理成功或失败的能力。

    【讨论】:

    • 感谢您抽出宝贵时间提供此答案,因为您绝对正确,应该更好地处理错误。我会更新我的代码。
    【解决方案2】:

    我已经想通了,但实际上我应该感谢 Scott Allen Ode to Code

    $.when() 等待解析的函数必须直接返回 promise()

    在我的例子中,我正在解析延迟对象并在 getCurrentLocation() 回调函数中返回 promise(),而不是我在 $.when() 中指定的函数。

    解决方案:

    var geoLocation = {
    
        getLocation: function() {
    
            var deferred = $.Deferred();
    
            // if geo location is supported
            if(navigator.geolocation) {
    
                // get current position and pass the results to getPostalCode or time out after 5 seconds if it fails
                navigator.geolocation.getCurrentPosition(deferred.resolve, this.geoLocationError, {
                    timeout: 5000
                });
    
            } else {
    
                //geo location isn't supported
                console.log('Your browser does not support Geo Location.');
            }
    
            return deferred.promise();
    
        },
    
        geoLocationError: function() {
            console.log('Geo Location failed.');
        }
    
    };
    
    $.when(geoLocation.getLocation()).then(function(data, textStatus, jqXHR) {
    
        console.log(data.coords.longitude, data.coords.latitude);
    
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多