#javascript #dom-events #titanium
#javascript #dom-события #titanium
Вопрос:
Я пытаюсь вызвать forwardGeocoder
функцию в titanium, но у меня возникают некоторые проблемы с получением результатов, рассмотрим следующий код :-
x = 0;
Ti.Geolocation.forwardGeocoder(startTextFieldContents, function(evt) {
var startPin = Ti.Map.createAnnotation({
longitude : evt.longitude,
latitude : evt.latitude,
pincolor : Ti.Map.ANNOTATION_GREEN
});
var startPinLocation = {
longitude : evt.longitude,
latitude : evt.latitude
}
mapview.addAnnotation(startPin);
x = 1;
});
Ti.API.log('X = ' x);
Если вы посмотрите на X, когда я выхожу из системы, оно ВСЕГДА равно 0, даже если я устанавливаю его внутри своей анонимной функции как 1, и поскольку это вызов функции с анонимной функцией в качестве аргумента, я изо всех сил пытаюсь понять, как получить это значение и сделать егодоступно за пределами forwardGeocoder.
Чтобы решить эту проблему, основываясь на том, что было сказано в этом сообщении, я использовал следующий код:
var completed = 0;
Ti.Geolocation.forwardGeocoder(startTextFieldContents, function(evt) {
var startPin = Ti.Map.createAnnotation({
longitude : evt.longitude,
latitude : evt.latitude,
pincolor : Ti.Map.ANNOTATION_GREEN
});
startPinLocation = {
longitude : evt.longitude,
latitude : evt.latitude
}
mapview.addAnnotation(startPin);
completed;
if (completed === 1) {
Ti.Geolocation.forwardGeocoder(finishTextFieldContents, function(evt) {
var finishPin = Ti.Map.createAnnotation({
longitude : evt.longitude,
latitude : evt.latitude,
pincolor : Ti.Map.ANNOTATION_RED
});
finishPinLocation = {
longitude : evt.longitude,
latitude : evt.latitude
}
mapview.addAnnotation(finishPin);
mapview.addRoute({
name : 'Route',
points : [startPinLocation, finishPinLocation],
color : 'green',
width : 1
});
});
}
});
Комментарии:
1. Это похоже на ваш последний вопрос, который я прокомментировал. Это асинхронно. Таким образом, вместо того, чтобы ваш код работал построчно, к чему вы привыкли, вы должны начать работать с моделью, управляемой событиями. Значение будет доступно в некоторый момент времени, когда данные будут получены с сервера. С этой целью вы передаете функцию, из которой значение будет доступно, и впредь для всего остального кода. Затем ваш журнал (и использование значений) должны поступать из анонимной функции, которую вы передаете.
2. Я понимаю, что вы говорите, и в моем предыдущем выпуске я смог использовать свой журнал внутри функции асинхронного события, чтобы получить свои результаты, проблема здесь в том, что я на самом деле запускаю два forwardGeocoders, один для начального местоположения и один для конечного местоположения, затем я хочу передать их веще одна функция, которая вычисляет маршрут между ними, поэтому критическая проблема заключается в том, что мне нужны как начальные, так и конечные переменные местоположения, но они находятся в пределах отдельных событий, поэтому кажется, что я могу добраться до одного, но не до другого.
3. Вы должны поместить их все друг в друга. Когда начальное местоположение найдено, найдите конечное местоположение. Когда конечное местоположение найдено, вы можете рассчитать маршрут, поскольку у вас есть все доступные данные.
4. Попробуйте изменить свою парадигму. Согласен, это немного более сложная проблема, поэтому давайте подумаем о некоторых решениях. Я опубликую несколько предложений ниже, а пока обновите вопрос подробностями в своем комментарии.
5. @Juhana это была моя первоначальная мысль, но проблема в том, что они по-прежнему недоступны друг другу одновременно.
Ответ №1:
Вы можете сделать так, как предложила Юхана, чтобы вложить вызовы. Проблема в том, что это происходит медленно. Вы ждете возврата с сервера и только затем начинаете следующий цикл, и только после 2 синхронных (т. Е. непараллельных) обходов вы выполняете требуемую задачу. Это было бы необходимо, если бы данные зависели друг от друга, хотя, похоже, это не так
Таким образом, вы можете сделать следующее:
var completed = 0, values = [];
function handle(data){
values.push(data);
completed;
if (completed === 2) {
dataReadySoLetsDoStuff();
}
}
fetchFromServer(params1, handle);
fetchFromServer(params2, handle);
function dataReadySoLetsDoStuff() {
// both values are ready
}
Вы видите, как это будет работать асинхронно? Существует небольшая проблема, заключающаяся в том, что вы не можете различать значения, потому что их порядок не гарантируется, но вы можете легко изменить handle
(например, каррировать, привязывать или переносить), чтобы исправить это.
Вы можете использовать другие подходы, хотя все они основаны на одной и той же идее — считайте выполненные задачи, пока я не гарантирую, что все они будут выполнены, а затем выполните задачу, которую мы хотели выполнить…
Комментарии:
1. Да, именно так я и собирался это сделать, но я вижу всевозможные проблемы, связанные с этим, в основном проблема скорости будет проблемой, и я все еще не уверен, что смогу получить оба местоположения из forwardGeocoder рядом друг с другом одновременно.
2. @bagwaa, я не вижу никаких проблем, не говоря уже о «всевозможных» из них. Какие проблемы со скоростью?
3. Проблема скорости, о которой я говорил, заключалась в том, что «Проблема в том, что это медленно. Вы ожидаете возврата с сервера и только после этого начинаете следующий раунд »
4. Я думаю, что теперь я отсортировал это, основываясь на приведенных здесь советах, в основном, вложите их и проверьте завершение события, опубликуйте то, что у меня получилось.
5. @bagwaa, не стесняйтесь делать все, что хотите, хотя я предлагаю не вкладывать вызовы, поскольку они независимы. Ваше решение будет работать, хотя для его работы не требуется количество завершений. Вы можете удалить эту переменную — вложенность позаботится об этом за вас, за счет более медленного пользовательского интерфейса.