Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   JavaScript .then() (https://javascript.ru/forum/misc/30194-javascript-then.html)

LaNaite 27.07.2012 13:48

JavaScript .then()
 
Всем привет!
Я начинаю изучать yandex.api 2.х для интеграции с 1С. Очень надеюсь здесь найти ответ. В документации к api есть метод geocode() который отвечает за прямое и обратное геокодирование.
Из 1С я хочу обращаться к методу geocode и в случае неудачного геокодирования заполнять таблицу адресами, которые не удалось отобразить на карте. Запрос geocode асинхронный.
Функционал я пытаюсь реализовать с помощью функции findPlacemarkOnMap(). Код ниже:

function findPlacemarkOnMap(adress, returnResult){
var myCollection = new ymaps.GeoObjectCollection();
ymaps.geocode(adress, {results: 1}).then(
function (res){
myCollection.add(res.geoObjects);
myMap.geoObjects.add(myCollection);	
if (myCollection.getLength() == 0) {returnResult = false} else {returnResult = true};
},
// Ошибка сервера или "плохие" входные данные
// Не срабатывает в случае неотображения объектов на карте
function (err){
alert(err.message);
});	
return returnResult;
}


Проблема в том, что return returnResult срабатывает раньше, чем выполняется код в конструкции .then()
Может я не в том месте присваивание прописываю или возврат?

vadim5june 27.07.2012 16:18

асинхронные функции в отличие от синхронных не возвращают значение с помощью return;
Вам надо из function (res){
вызвать функцию обработчик передав в качестве параметра returnResult
примерно вот так
if (myCollection.getLength() == 0) {returnResult = false} else {returnResult = true};callback(returnResult)

LaNaite 27.07.2012 16:54

Вадим, Спасибо!
Подскажите, пожалуйста, как передать callback-функцию в запрос. Если не сложно - на моем примере.

vadim5june 27.07.2012 17:05

Цитата:

Сообщение от LaNaite (Сообщение 192111)
Вадим, Спасибо!
Подскажите, пожалуйста, как передать callback-функцию в запрос. Если не сложно - на моем примере.

мне непонятно зачем Вы returnResult передаете в качесиве аргумента-логично было бы так написать
function findPlacemarkOnMap(adress,callback){
.......
var returnResult;
if (myCollection.getLength() == 0) {returnResult = false} else {returnResult = true};callback(returnResult);},
function (err){
alert(err.message);
});
};
function callback(r){alert(r)};

LaNaite 27.07.2012 17:36

Спасибо! Все получилось)

LaNaite 28.07.2012 22:37

Вадим, и снова здравствуйте)
Возникла необходимость в продолжении.

Мне нужно организовать обращение к некоторой функции, которая будет вызывать результат геокодирования (не асинхронно).

Если я напишу:

function getResult(){
var result;
findPlacemarkOnMap(adress, result);
return result;
}

То несмотря на использование callback-функции getResult() вернет undefined. Есть какие-нибудь "обходы" асинхронности?

melky 28.07.2012 22:42

Цитата:

Сообщение от LaNaite
Есть какие-нибудь "обходы" асинхронности?

это не карты яндекса, но из той же басни.
http://javascript.ru/forum/174893-post67.html

т.е. только через указание callback, в котором можно будет использовать результаты геокодирования.

vadim5june 28.07.2012 22:55

Цитата:

Сообщение от LaNaite (Сообщение 192505)
Мне нужно организовать обращение к некоторой функции, которая будет вызывать результат геокодирования (не асинхронно).

Так из за чего асинхронность потому что сам поцесс получения геокодирования длительный асинхронный-там запрос на сервер идет и функция callback выполняется значительно позже(на десятки миллисекунд) чем Ваша функция getResult
поэтому getResult всегда вернет undefined
Обойти нельзя-по крайней мере это мое мнение
а что Вы не работаете с callback функцией-ее Вы можете задать в любом месте и любого вида-
Ps прочтите так же по ссылке melky то же самое работать через callback функцию

LaNaite 28.07.2012 23:36

Ох, жесть)) я с ajax вообще не знаю как работать.
Я поняла, что в примере с сайта надо изменить Параметр async на false. Но что находится в url, и где надо указать мою функцию findPlacemarkOnMap() (и нужно ли в этом случае передавать в нее Callback)? Прошу прощения, если задаю смешные вопрос, я не спец в этом, пытаюсь разбираться.


function req(){
return $.ajax({
async: false;
url: '/foo.php',
method: 'GET',
success: function(data){
return data;
}
});
}
var myData = req();
alert(myData);

melky 28.07.2012 23:51

Цитата:

Сообщение от LaNaite
Ох, жесть)) я с ajax вообще не знаю как работать.

и фиг с ним.

разжую : в сделать задуманное не получится, использовать результат придётся не из return'а, а из функции-callback'a.

vadim5june 28.07.2012 23:51

Цитата:

Сообщение от LaNaite (Сообщение 192526)
Ох, жесть))

Это просто для примера ссылка-к Вам непосредственно отношение не имеет-у Вас нельзя повидимому задать синхронный способ выполнения(смотрите инструкцию к функции findPlacemarkOnMap)
Поэтому с аяксом не разбирайтесь
У вас есть какая то функция куда Вы хотите передать результат callback-так сделайте callback -ом всю вашу функцию

LaNaite 28.07.2012 23:53

т.е. если я обращаюсь к запросу js из стороннего приложения, то получить его результат (на сторону приложения) - не получится?

LaNaite 28.07.2012 23:55

не могу. обрабатываться результат должен не в js, а в стороннем приложении (1с)

melky 28.07.2012 23:59

Цитата:

Сообщение от LaNaite (Сообщение 192536)
не могу. обрабатываться результат должен не в js, а в стороннем приложении (1с)

если нельзя отсрочить обработку результата - то низзя.

LaNaite 29.07.2012 00:01

отсрочить - эт как?)

vadim5june 29.07.2012 00:03

Цитата:

Сообщение от LaNaite (Сообщение 192536)
не могу. обрабатываться результат должен не в js, а в стороннем приложении (1с)

Нет синхронно не получится потому что на запрос время надо
Если можно так чтобы сначала обратится к геолокации записать результат куда то а потом уже передать в 1С
или периодически обращайтесь к геолокации каждую секунду результат записывайте в переменную а 1С когда обратится возьмет последнее значение

LaNaite 29.07.2012 00:18

Можно.
Например в глобальную переменную?
Я сейчас сделала так, что в callback функции происходит изменение глобальной переменной на результат, который она получила в findPlacemarkOnMap(). И я создала новую функцию, которая возвращает глобальную переменную:

function getGlobalResult(){

alert(returnResult);
//return returnResult;
}

Из 1С я поочереди вызываю сначала: findPlacemarkOnMap, затем getGlobalResult. Все равно Undefined

Aetae 29.07.2012 00:33

Попробую и я обьяснить почему так, т.е. суть асинхронности.
Выполняется код,
выполняется,
выполняется,
выполняется по порядку,
тут раз - и асинхроннный запрос запросил что-то от сервера,
сервер думает, а код выполняется дальше по порядку,
сервер думает, а код выполняется дальше,
сервер думает, а код выполняется дальше,
внезапно сервер законцил думать и вернул результат, в связи с чем была вызвана функция callback прямо во время выполнения какой-то другой части кода.
выпоненен callback(),
код выполняется дальше,
код выполняется дальше...

Или даже так(в вашем случае):
Выполняется код,
выполняется,
выполняется,
выполняется по порядку,
тут раз - и асинхроннный запрос запросил что-то от сервера,
сервер думает, а код выполняется дальше по порядку,
сервер думает, а оставшийся код уже полностью выполнен и ничего не происходиит,
сервер думает, ничего более не происходиит,
внезапно сервер законцил думать и вернул результат, в связи с чем была вызвана функция callback.
выпоненен callback(),
ничего более не происходиит...


Т.о. вы вызываете функцию когда сервер ещё не закончил думать. Естесно переменная ещё undefined.
В яндексе работают умные ребята, там должны быть функции для таких случаев. Накрайняк обращаться к переменной с интервалом до тех пор пока там не появитсчся значение.

LaNaite 29.07.2012 00:36

Спасибо. Я это понимаю. Сейчас пытаюсь понять - есть ли какие-то методы - позволяющие реализовать мою задачу. Если бы я писала код для интернет-сервиса - проблем бы не было. Но я использую передачу параметров.

vadim5june 29.07.2012 00:46

Цитата:

Сообщение от LaNaite (Сообщение 192566)
. Но я использую передачу параметров.

а adress Вы откуда получаете-из 1С?
и Вам нужен результат геолокаци с этим адресом
нужно общение с 1С тоже асинхронным сделать-сначала он передат Вам
adress в одну функцию а потом когда у Вас будет результат Вы передадите в 1С его

LaNaite 29.07.2012 00:57

Повесила геокодирование и получение результатов геокодирования на разные кнопки. Неудобно конечно... но работает(

vadim5june 30.07.2012 08:06

Цитата:

Сообщение от LaNaite (Сообщение 192578)
. Неудобно конечно... но работает(

а что мы имеем со стороны 1С?
Что такое adress
Что за программа бухгалтерская или битрикс-и зачем там геолокация
Почему нельзя оттуда отправить асинхронный запрос?


Часовой пояс GMT +3, время: 20:08.