javascript/jquery中函数的执行

Execution of function in javascript/jquery

我有一个让用户长期使用的功能。我需要根据用户位置将其设置为 return url url 会有所不同。 returned url 用于 ajax 调用。然而,这第二个 ajax 调用在我的第一个函数完成之前被命中,然后给出 404,因为 url 未定义。

所以我的代码是:

$(document).ready(function () {
   getLatLong();

   if (!hasTicket) {
        doAction();
    } else {
        doAnotherAction();
        $.unblockUI();
    }
});

function doAction() {
         $.ajax({
            url: url, // this is where I am failing
            type: 'POST',
            success: function (response) {
                ticket = response.data.ticket;
                $.unblockUI();
            },
            error: function (xhr) {
                $.unblockUI();
                errorHandler("Failed" + xhr.status);
            }
        });
}

function getLatLong() {
    if (Modernizr.geolocation) {
        navigator.geolocation.getCurrentPosition(
            function (position) {
                getUrl(position.coords.latitude, position.coords.longitude);
            },
            getUrlFallback,
            { enableHighAccuracy: false, timeout: 10000, maximumAge: 360000 }
        );
    } else {
        getUrlFallback();
    }
}

function getUrl(latitude, longitude) {
    $.ajax({
        url: 'api/Controller/Action',
        type: 'GET',
        async: false, // tried making this synchronous
        data: {
            latitude: latitude,
            longitude: longitude
        },
        success: function (data) {
            url = data;
        },
        error: function (xhr) {
            errorHandler("Failed to get users nearest url: " + xhr.status);
        }
    });
}

所以我调用 getLatLong,然后调用我的 getUrl ajax 函数,该函数将 async 设置为 false 但是我认为它是 return 首先从 getLatLong 调用我的 doAction 函数并且 url 然后变得不确定。

如何确保 getLatLong 和 getUrl 在 doAction 运行之前完全完成?

我试图复制在调用 getLatLong() 之后发生的功能;进入一个函数并使用 $.when adn .then 如下但它仍然在 url 设置之前进入 doAction 方法。

function callAction() {
       if (!hasTicket) {
            doAction();
        } else {
            doAnotherAction();
            $.unblockUI();
        }
}

然后我在文档中准备了以下内容:

$(document).ready(function () {

    $.when(getLatLong()).then(callAction());
});

编辑 - 使用 getUrlFallback 函数更新

function getUrlFallback () {
    // uses 3rd party geoPlugin
    getUrl(geoplugin_latitude(), geoplugin_longitude());
}

您可以将 getLatLong 调用转换为 return jQuery Promise:

(注意:我没有在此处包含 getUrlFallback 逻辑,因为您没有包含该代码,所以我不知道它应该做什么):

function getLatLong() {
    return $.Deferred(function(def) {
         if (!Modernizr.geolocation) {
             def.resolve(geoplugin_latitude(), geoplugin_longitude());
         } else {
             navigator.geolocation.getCurrentPosition(
                 function(position) {
                     def.resolve(position.coords.latitude, position.coords.longitude);
                 },
                 def.resolve(geoplugin_latitude(), geopugin_longitude()),
                 { enableHighAccuracy: false, timeout: 10000, maximumAge: 360000 }
             );
         }
    }).promise();
}

并修改 getUrl,使其 return 成为 $.ajax 的结果,并省略 successerror 回调:

function getUrl(latitude, longitude) {
    return $.ajax(...);
}

所以你现在可以使用:

getLatLong().then(getUrl).then(callAction);   // NB: no () after callAction

callAction 将自动传递给 URL,而不是存储在外部范围的变量中。

现在请注意 getLatLong 函数现在具体是如何做到这一点的,而且只做到这一点。它随后不会尝试将 lat/long 转换为 URL,因为 getUrl 会为您完成(无论 URL 来自 GeoAPI 还是 geoplugin ).