Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Как остановить работу ЦИКЛа пока функция не вернет ответ? (https://javascript.ru/forum/misc/53951-kak-ostanovit-rabotu-cikla-poka-funkciya-ne-vernet-otvet.html)

Poveritov 25.02.2015 13:07

Как остановить работу ЦИКЛа пока функция не вернет ответ?
 
Столкнулся с вопросом, требуется помощь в его решении:
Есть элемент кода
function my_funct(){
	var  len = 20;
	var items;
	for (var i=0; i<len; i++){
			func_request("example_url.php",{param1:value, param2:value2}, function(answer){
				items = answer.response[0].value;
			});
		alert(items);
	}
}

в функции my_funct() выполняется цикл, по идее, с каждой итерации должна выполняться функция func_request, которая бы возвращала определенные значения.
Проблема заключается в том, что функция не успевает вернуть значения answer, а цикл продолжает работать дальше и к момент возвращения функцией значения цикл уже закончил свою работу.
При этом постоянно выводится alert пустой.

Вопрос, как сделать так, чтобы цикл увеличивал итерацию только после того, как ответ получен и передан в переменную items?

Skipp 25.02.2015 13:19

Выполняйте синхронные запросы

Erolast 25.02.2015 13:19

Очевидно, выполнять запрос синхронно. Как - сам уж смотри в документации этого своего func_request.
Хотя лучше так не делать - любое взаимодействие со страницей (даже простая прокрутка) заблокируется до прибытия ответа. Лучше перестраивай код на асинхронность - например, перетащи алерт в коллбек.

ksa 25.02.2015 13:46

Цитата:

Сообщение от Poveritov
как сделать так, чтобы цикл увеличивал итерацию только после того, как ответ получен и передан в переменную items?

Если это краеугольная задача - выкинуть тот цикл и сделать все через setTimeout()...

Poveritov 25.02.2015 14:19

это краеугольная задача, синхронное выполнение не подойдет, так как при этом пользователь может осуществлять действия. Я рассматривал вариант setTimeout(), но там ведь вторым параметром передается время задержки... в моем случае неизвестно, через какое время сервер вернет результат. Из практики это может быть и 3 сек. и 5 сек. Можно ли как-то обойти параметр "время задержки"?

Erolast 25.02.2015 14:20

Работать асинхронно для слабаков?
Чтобы избежать ада коллбеков, существуют обещания. Не забудь заполифиллить для старых браузеров.

Poveritov 25.02.2015 14:22

Цитата:

Сообщение от ksa (Сообщение 358345)
Если это краеугольная задача - выкинуть тот цикл и сделать все через setTimeout()...

Цитата:

Сообщение от Erolast (Сообщение 358338)
Очевидно, выполнять запрос синхронно. Как - сам уж смотри в документации этого своего func_request.
Хотя лучше так не делать - любое взаимодействие со страницей (даже простая прокрутка) заблокируется до прибытия ответа. Лучше перестраивай код на асинхронность - например, перетащи алерт в коллбек.

Тут больше не в алерте дело, а в том, что мне нужно вытащить значение за пределы функции func_request (алерт взять для примера, чтобы показать, что переменная items не успевает принять значение).

Erolast 25.02.2015 14:24

http://learn.javascript.ru/callbacks
https://developer.mozilla.org/en-US/...ts/Promise/all
Да, функции принято называть глаголами и с маленькой буквы.

ksa 25.02.2015 14:26

Цитата:

Сообщение от Poveritov
Я рассматривал вариант setTimeout(), но там ведь вторым параметром передается время задержки... в моем случае неизвестно, через какое время сервер вернет результат.

setTimeout() нужен только т.с. старта всего действа. Потом все передается в колбек функции. А они у тебя вроде как есть...
При получении ответа - стартуй следующую итерацию и так далее пока "цикл не закончится"... ;)

Erolast 25.02.2015 14:36

Цитата:

http://learn.javascript.ru/callbacks
https://developer.mozilla.org/en-US/...ts/Promise/all
Да, функции принято называть глаголами и с маленькой буквы.
Если для запроса используется jQuery - он уже поддерживает собственную реализацию промайзов.
function fart(amount, doAfter) {
    var requests = [];
    
    for (var i = 0; i < amount; i++) {
        var request = $.post("fart.php", function(response) {
            console.log(response);
        });
        requests.push(request);
    }
    
    $.when(requests).done(doAfter)
}

fart(20, function() {
    alert("Фух... кончилось");
})


@ksa - а зачем? Асинхронность ж никуда не уходит.


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