如何使用延迟对象通过HTML5 Geolocation API检索经度和纬度?

时间:2014-09-21 22:53:29

标签: jquery geolocation promise deferred

我想使用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未定义的错误。我认为它与我定义延迟对象的范围有关,但我不确定。我错过了什么?

2 个答案:

答案 0 :(得分:6)

迈克尔,在阅读了Hackaholic的答案和你自己的答案之后,两者都会处理成功返回的数据,但错误可以更好地处理。

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

同样,承诺拒绝也可用于传递您自己的“您的浏览器不支持地理位置”错误的承诺链。

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();
    } 
};

忽略注释,这非常紧凑,并注意geoLocation.getLocation()如何不尝试处理错误,但使它们可用于调用函数的错误处理程序。

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

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

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

答案 1 :(得分:2)

我已经明白了,但实际上我应该在Ode to Code认可Scott Allen。

$.when()等待解决的功能必须直接返回promise()

就我而言,我正在解析延迟对象并在promise()回调函数中返回getCurrentLocation(),而不是我在$.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);

});