如何从JS中的异步操作获取值?

时间:2018-10-20 20:31:18

标签: javascript ajax geolocation

我已经阅读了一些论坛,并观看了一些有关异步操作并使用诺言来解决此类问题的youtube视频,但它们仅用于更简单的功能等。它实际上并没有给我提示如何解决我的问题。 我的脚本中有此功能。

var coordinates = [];
    $(function(){
      function getcoordinates(){
          if(navigator.geolocation){
            var options = {
              enableHighAccuracy: true,
              timeout: 5000,
              maximumAge: 0
            };
             function success(pos) {
                var crd = pos.coords;
                userlat = crd.latitude;//this one
                userlong = crd.longitude;// and this one are the ones i want
              }
              function error(err) {
                console.warn(`ERROR(${err.code}): ${err.message}`);
              }
            navigator.geolocation.getCurrentPosition(success, error, options);//but I dont have an idea how to access those two from this API function.
          }
          else
            alert("Geolocation is not supported by this browser.");
        }

      $('#go').click(function(){
        console.log("outside success output: " + userlat);//this still shows 0
        console.log(coordinates);

        $.ajax({
          url:"dbphp.php",
          method:"POST",
          data:{userlong:coordinates[1], userlat:coordinates[2]},
          success:function(data){
          }
        })

      })
    })

如何返回userlat和userlong的值并将其放入坐标数组?

1 个答案:

答案 0 :(得分:0)

首先让我们就您所谓的“异步”的定义达成一致:非阻塞代码段,稍后将在条件满足时执行该代码?

根据这个定义,您的代码中有navigator.geolocation.getCurrentPosition()$.ajax(),还有.click()$()还有一些“异步”调用。

每一个都将回调您提供的提供的功能(回调)。

对于getCurrentPosition(),它接收3个参数,其中2个是分别在成功/失败时执行的回调(可选)和一个配置对象(可选)。而且您肯定会处理好。

但是:

  1. 您的语法似乎有点错误,getcoordinates()并非由单击按钮之前的任何东西触发的
  2. 无论哪种方式,您都不需要在getcoordinates()处理程序中处理返回的值之前就专门等待.click()完成
  3. 您不应过多地定义函数定义
  4. userlatuserlong声明在哪里?
  5. 不要忘记数组的索引为0

TL; DR 玩这个:

function getCoordinates(thenCb, errorCb) {
    thenCb = thenCb || function () {};
    errorCb = errorCb || function () {};

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
        });
    } else {
        alert('Geolocation is not supported by this browser.');
    }
}

$(function () {
    $('#go').click(function () {
        getCoordinates(function (pos) {
            $.ajax({
                url: 'dbphp.php',
                method: 'POST',
                data: { 
                    userlong: pos.coords.latitude, 
                    userlat: pos.coords.longitude 
                },
                success: function (data) {
                    // do stuff with data...
                }
            });
        }, function (err) {
            console.warn('Geolocation error ' + err.code + ': ' + err.message);
        });
    });
});

对于ES6 +版本:

const getCoordinates = (thenCb = () => {}, errorCb = () => {}) => {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(thenCb, errorCb, {
            enableHighAccuracy: true,
            timeout: 5000,
            maximumAge: 0
        });
    } else {
        alert('Geolocation is not supported by this browser.');
    }
};

$(() => {
    $('#go').click(() => {
        getCoordinates(({ coords }) => {
            const { userlong, userlat } = coords;
            $.ajax({
                url: 'dbphp.php',
                method: 'POST',
                data: { userlong, userlat },
                success: (data) => {
                    // do stuff with data...
                }
            });
        }, (err) => {
            console.warn(`Geolocation error ${err.code}: ${err.message}`);
        });
    });
});

注1:您可能希望根据自己的需要和上下文进行重构,避免在全局范围内设置getCoordinates(),等等。

注2:在这种情况下,可以等待用户单击getCoordinates()完成,因为尽管“异步”,该函数的确会迅速返回结果。通常,当解析时间较长时,您可能需要a)在点击处理程序之前触发函数以记住其返回值,b)向用户显示加载状态。

关于xhr请求,请注意您正在使用jQuery.ajax(),并且响应数据将在您的success回调中作为其第一个参数提供。

此外,请务必查看文档:
-https://developer.mozilla.org/en-US/docs/Web/API/Geolocation
-https://api.jquery.com

如果有兴趣,请阅读如何使用Promises,以使回调代码更具摘要性:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

如果仍然感兴趣,请阅读如何使用async / await来使Promises代码更具摘要性:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function