我有一个让用户拉长的功能。我需要根据用户位置返回一个url,url会有所不同。返回的url用于ajax调用。然而,第二个ajax调用在我的第一个函数完成之前被命中,然后在未定义url的情况下给出404.
所以我的代码是:
$(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但是我认为它首先从getLatLong返回,因为我的doAction函数被调用,然后url变得未定义。
如何在doAction运行之前确保getLatLong和getUrl完全完成?
我试图复制调用getLatLong()之后发生的功能;进入一个函数并使用$ .when adn .then如下所示,但在url设置之前它仍然进入doAction方法。
function callAction() {
if (!hasTicket) {
doAction();
} else {
doAnotherAction();
$.unblockUI();
}
}
然后我在doc中准备了以下内容:
$(document).ready(function () {
$.when(getLatLong()).then(callAction());
});
编辑 - 使用getUrlFallback函数更新
function getUrlFallback () {
// uses 3rd party geoPlugin
getUrl(geoplugin_latitude(), geoplugin_longitude());
}
答案 0 :(得分:1)
您可以将getLatLong
调用转换为返回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
的结果,并省略success
和error
回调:
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
)。