Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / Асинхронная функция. как дождаться ее выполнения? / 13 сообщений из 13, страница 1 из 1
12.02.2019, 14:38
    #39772854
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Здравствуйте.
В приложении используется API яндекс карт. На вход приходит json с данными объектов: название, адрес, координаты. Задача - разместить объекты на карте, название вывести в хинт. Это проблем не вызывает. Но проблема все-таки есть: у некоторых объектов не указаны координаты. Поэтому приходится использовать геокодирование, по адресу определяются координаты. Но геокодирование выполняется асинхронно, а json обрабатывается в цикле. В результате получаю объект на карте с правильными координатами, но название совсем из другого объекта.
Поэтому такой вопрос: как дождаться завершения работы асинхронной функции, и только потом продолжить выполнение цикла?
...
Рейтинг: 0 / 0
12.02.2019, 23:13
    #39773087
Изопропил
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Павел Гужанов,

Развернуть цикл в последовательность асинхронных вызовов
...
Рейтинг: 0 / 0
13.02.2019, 03:51
    #39773113
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Павел Гужанов,

в новом экмаскрипте появились асинхронные функции
гуглите слова async и await. С их помощью можно реализовать необходимое (caniuse заявляет поддержку 85.3% процента, но остальные - это разные динозавры, которые сидят на браузерах с релизом до июня 2017-ого года, типа IE... то есть не обновляются уже почти 2 года)

Ну а если нет, то можно воспользоваться jquery.done(), а можно поменять очерёдность задач и сначала получить все геоданные, после чего приступить ко всему остальному.
...
Рейтинг: 0 / 0
13.02.2019, 11:57
    #39773258
Лысый дядька
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Програмёрв новом экмаскрипте появились асинхронные функции
гуглите слова async и await. С их помощью можно реализовать необходимое (caniuse заявляет поддержку 85.3% процента, но остальные - это разные динозавры, которые сидят на браузерах с релизом до июня 2017-ого года, типа IE... то есть не обновляются уже почти 2 года)

А babel сейчас уже не моден что ли?
...
Рейтинг: 0 / 0
13.02.2019, 13:04
    #39773302
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Лысый дядькаПрограмёрв новом экмаскрипте появились асинхронные функции
гуглите слова async и await. С их помощью можно реализовать необходимое (caniuse заявляет поддержку 85.3% процента, но остальные - это разные динозавры, которые сидят на браузерах с релизом до июня 2017-ого года, типа IE... то есть не обновляются уже почти 2 года)

А babel сейчас уже не моден что ли?

Ну вообще я разными трансляторами в джаваскрипт никогда не пользовался :) Как-то не было необходимости. Так что может быть и моден, но я не в курсе :)
...
Рейтинг: 0 / 0
13.02.2019, 14:05
    #39773356
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
ПрограмёрПавел Гужанов,

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

Я так и делаю. Запускаю функцию, которая получает геоданные и добавляет их в объекты.
А потом запускается функция, которая по всему списку объектов проходит в цикле, и добавляет их на карту. Но вот в чем проблема: геоданные в объекты добавляются асинхронно, и вторая функция запускается раньше, чем они добавятся.
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
// символ $ - это данные, передаваемые из приложения
var myMap;
var dataStr;
var len = ${length};

ymaps.ready(init);


function init () {

	myMap = new ymaps.Map('map', {
	center: [${moscowCoord}], // Москва
	zoom: 10,
	controls: ['zoomControl', 'searchControl', 'typeSelector',  'fullscreenControl', 'routeButtonControl', 'trafficControl', 'rulerControl']
	}, {
	searchControlProvider: 'yandex#search'
	});
        dataStr = ${str};
	fillAll();
// addToMap выполняется, не дождавшись завершения fillAll
// Как тут быть?
	addToMap();
}

function fillAll(){
	    for(var i = 0; i < len; i++ ){
		    	if(dataStr[i]['lat'] == ''){
		    		 var st = ${str}[i];
		    		fill(st, i));
		    	}
		    	else{
		    		continue;
		    	}	
		    }
		    
		    
		}
		
		function fill(st, i){
			ymaps.geocode(st.addr, {
				results: 1
			}).then(function(res){
				var obj = res.geoObjects.get(0);
				var coord = obj.geometry._coordinates;
				lat = coord[1];
				lon = coord[0];
				st.lat = lat;
				st.long = lon;
				 dataStr[i] = st;
			});
		}

function addToMap(){
	    	for(i = 0; i < len; i++){

		    	var str = dataStr[i];
	    		lat = str.lat * 1;
		    	lon = str.long * 1;
		    	var data = getBaloon(str); // тут получается балун 
				
		    	var iconName = getIconName(str);
		    	var name = str.name; 
		    	
		    	myMap.geoObjects
		        .add(new ymaps.Placemark([lon, lat], {
		            balloonContent: data,
		            hintContent: name
		        }, {
	
		            iconLayout: 'default#image',
		            // Своё изображение иконки метки.
		            iconImageHref: 'images/' + iconName + ".png",
		            // Размеры метки.
		            iconImageSize: [width, height],
	
		        }));
	
	    	}
		}
...
Рейтинг: 0 / 0
13.02.2019, 14:11
    #39773361
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Если в приведенном коде функцию addToMap запустить через таймаут в 2 секунды, все работает нормально. Но это, как мне кажется, неправильно. Сейчас у меня в исходных данных 250 записей, всего у двух нет координат. А если будет больше? двух секунд может не хватить.
...
Рейтинг: 0 / 0
13.02.2019, 14:43
    #39773402
Barlone
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Павел ГужановЕсли в приведенном коде функцию addToMap запустить через таймаут в 2 секунды, все работает нормально. Но это, как мне кажется, неправильно. Сейчас у меня в исходных данных 250 записей, всего у двух нет координат. А если будет больше? двух секунд может не хватить.Выкинуть функцию addToMap, добавлять объект на карту при получении данных.
...
Рейтинг: 0 / 0
13.02.2019, 14:47
    #39773408
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Павел Гужанов,

У Вас там что-то с отступами напутано, сложно понять что во что вложено, ну да ладно :)

Самый простой способ, как мне кажется, который не заставит переписывать половину кода: заюзать jquery события (кастомные). В начале вызова функции fill дёргаем событие fillStart, при завершении функции (в конце отработки then) дёргаем fillEnd. Обработчики событий инкапсулируем в блоке, в котором вводим переменную-счётчик (чтобы добиться замыканием возможность обоих обработчиков менять её значение). Тогда в обработчике fillStart инкрементим счётчик, а в fillEnd декрементим, и если после декремента обнаруживается, что счётчик обнулился, дёргаем событие allFillEnd, в котором и вызываем addToMap.

Всего дополнительных строчек 8-10 кода :) Хотя мой внутренний перфекционист кричит, что это не круто, видимо если переписать код целиком, то можно это сделать намного лучше, но тут надо сидеть, думать и проектировать. Наверное задача того не стоит, слишком дорогая получится :))
...
Рейтинг: 0 / 0
13.02.2019, 14:57
    #39773418
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
BarloneВыкинуть функцию addToMap, добавлять объект на карту при получении данных.

так и было сделано сначала. В результате все добавлялось, но у объектов, у которых не были заполнены координаты, Хинт и балун получались не свои, а от объектов, последних в массиве.
...
Рейтинг: 0 / 0
14.02.2019, 10:52
    #39773730
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Програмёр,

Смысл вашего ответа понятен, а вот как реализовать - не пойму. Смотрю статьи по событиям в javascript и iquery, везде в примерах события привязываются к окну или к компоненту. Мне же надо просто объявить события в коде, и по меревыполнения кода эти события происходят.
Можете дать маленький пример, как реализовать то, что вы написали?
...
Рейтинг: 0 / 0
14.02.2019, 11:19
    #39773744
Програмёр
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Павел ГужановПрограмёр,

Смысл вашего ответа понятен, а вот как реализовать - не пойму. Смотрю статьи по событиям в javascript и iquery, везде в примерах события привязываются к окну или к компоненту. Мне же надо просто объявить события в коде, и по меревыполнения кода эти события происходят.
Можете дать маленький пример, как реализовать то, что вы написали?

Что-то типа такого
Код: javascript
1.
2.
3.
4.
5.
6.
7.
// в основном коде в цикле
$('body').trigger('fillStart');

// ну и объявление самого обработчика
$('body').on('fillStart', function(){
    // тут инкремент
});



Разумеется желательно ещё использовать namespace в событиях (ну так, чтобы отделить их от других явно), и если есть возможность, то лучше вешать их не на боди, а на те элементы, к которым они относятся.

fillEnd по аналогии :) Только их оба до этого надо обернуть в анонимную функцию, как я и говорил, с переменной, которая будет видна в обоих и будет инкрементиться/декрементиться ими.
...
Рейтинг: 0 / 0
14.02.2019, 11:41
    #39773762
Павел Гужанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная функция. как дождаться ее выполнения?
Програмёр,

Спасибо, вроде понятно, буду разбираться
...
Рейтинг: 0 / 0
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / Асинхронная функция. как дождаться ее выполнения? / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]