У меня странная проблема: я в течение последних нескольких часов вбивал голову в стену.
Я работаю над приложением для iPhone в Appcelerator Titanium, и в настоящее время оно хочет подождатьпока другой код не будет запущен до получения результатов нескольких запросов HTTPClient, несмотря на то, что я вызываю их, прежде чем пытаюсь использовать их результаты. Сначала вызывается
function getMarkers(e, miles){ //The function with the HTTPClient calls that are firing last, trimmed to have only the relevant code.
var markers = [];
Ti.API.info("Getting markers");
xhr.onload = function()
{
var data = Ti.XML.parseString(this.responseText);
var ref = data.documentElement.getElementsByTagName("reference");
for(var i =0; i < ref.length; i++){
var marker = new Object();
marker.ref = ref.item(i).text;
var request = Titanium.Network.createHTTPClient();
request.setTimeout(10000);
request.onload = function(){
var data = Ti.XML.parseString(this.responseText);
marker.address = data.documentElement.getElementsByTagName("formatted_address").item(0).text;
if(data.documentElement.getElementsByTagName("formatted_phone_number") != null){
marker.phone = data.documentElement.getElementsByTagName("formatted_phone_number").item(0).text;
} else {
marker.phone = null;
}
marker.icon = data.documentElement.getElementsByTagName("icon").item(0).text;
marker.lat = data.documentElement.getElementsByTagName("lat").item(0).text;
marker.lng = data.documentElement.getElementsByTagName("lng").item(0).text;
marker.name = data.documentElement.getElementsByTagName("name").item(0).text;
if(data.documentElement.getElementsByTagName("url") != null) {
marker.url = data.documentElement.getElementsByTagName("url").item(0).text;
} else {
marker.url = null;
}
markers.push(marker);
Ti.API.info(markers.length);
}
request.open("GET","https://maps.googleapis.com/maps/api/place/details/xml?reference=" + marker.ref + "&sensor=true&key=" + Ti.App.apiKey);
request.send();
}
};
xhr.open("GET","https://maps.googleapis.com/maps/api/place/search/xml?location=" + googleLatLng + "&radius=" + radius + "&types=" + Ti.App.types + "&sensor=true&key=" + Ti.App.apiKey);
xhr.send();
return markers;
}
// actually draw the markers on the map
function drawMap(markers, currentLoc)
{
var i;
Ti.API.info("Adding markers...");
for(i=0;i<markers.length;i++)
{
Ti.API.info("Marker " + i);
Ti.API.info(markers[i].name);
var ann = Titanium.Map.createAnnotation({
image:markers[i].icon,
animate:true,
latitude:markers[i].lat,
longitude:markers[i].lng,
title:markers[i].name,
subtitle:markers[i].address
});
if(markers[i].url != null){
ann.rightButton = markers[i].url;
}
mapview.addAnnotation(ann);
}
Ti.API.info("Markers added"); //When this block is called, markers.length == 0
}
// find the user's location and mark it on the map
function waitForLocation(e)
{
//Do stuff about finding current location and marking it on the map. This stuff works and a pin drops for the current location
drawMap(getMarkers(e), currentLoc);
}
waitForLocation, который затемназывает остальных.Xcode выводит следующее:
[INFO] Getting markers
[INFO] Adding markers...
[INFO] Markers added
[INFO] 1
[INFO] 2
[INFO] 3
[INFO] 4
Это означает, что он входит в функцию getMarkers (первая строка), затем покидает ее (следующие две строки), затем возвращается к функции getMarkers для фактического получения маркеров (последние четыре строки, вывод markers.length
при добавлении каждого маркера).Зная, что
я переместил вызов .open()
до вызова .onload()
, основываясь на ответе, найденном здесь, но я получаю то же самое, независимо от того, находится .open()
до или после .onload()
.
Я нашел информацию о том, что вызов httpClient выполняет свою задачу асинхронно (важная информация, которой не хватает в справочнике по API).Зная об этом, имеет смысл, что он покидает функцию, но он не понимает, как обрабатывается информация, так как мне нужны загруженные маркеры, прежде чем пытаться добавить их.
Говоря с моим коллегой по разработке для iPhone, он упомянул, что обрабатывает их, используя делегат и вызов Delegate.connectionDidFinishLoading.Может быть, есть ли способ подключиться к этому, или реализация Titanium, которую я мог бы использовать?
Есть ли еще один хороший способ убедиться, что он не пытается загрузить маркеры раньше?приложение фактически загрузило их?Он должен работать только на iPhone, поэтому параметры, подходящие для iPhone, подойдут.