LINUX.ORG.RU

Синхронизация выполнения

 


0

1

Познаю js. Как частично убрать асинхронное выполнение кода? Например, следующий код.

for (i=0; i<3; i++) {
	console.log ( "i=" + i );
	// запрос к серверу
	VK.api (...,..., function (data) { console.log ( "i=" + i + ", data=" + data.response ) });
}

console.out ( "end of FOR" );

что мы видим в консоли

i=0
i=1
i=2
end of FOR
i=2, data=data0
i=2, data=data1
i=2, data=data2

а хотелось бы

i=0
i=0, data=data0
i=1
i=1, data=data1
i=2
i=2, data=data2
end of FOR

Иными словами - как корректно синхронизировать выполнение кода и запросов? Если можно, с примерами.

★★★★★

Последнее исправление: anonymous_sapiens (всего исправлений: 1)

Бред моде ОН.

var i = 0
while (true) {
	console.out ( "i=" + i );
	// запрос к серверу
	VK.api (...,..., function (data) { i++; console.log ( "i=" + i + ", data=" + data.response ) });
if (i == 3) break;
}

console.out ( "end of WHILE" );

habamax ★★★
()
Ответ на: комментарий от habamax

Нет, к сожалению такой вариант не подойдет.

Я же гуглил, про jQuery.when, .done, .ajax {async=false} читал, но до меня это с трудом доходит, а примеры этих методов заработали опять не так, как мне хотелось бы.

Их упоминания в книжках по jquery Бибо-Катца и Бенедетти-Кренли не нашел. Поэтому и спрашиваю у Лора. Задача, как мне кажется, тривиальная.

anonymous_sapiens ★★★★★
() автор топика
Ответ на: комментарий от habamax

будешь делать запросы к VK до тех пор пока первые три не ответят? ;)

ТС: то, чего тебе хочется, будет только последовательным выполнением запросов (ну сам подумай, послать 3 запроса на сервер в параллель и ожидать что они выполнятся по-очереди - нельзя)

схематический код:


var i = 0;
function foo() {
  VK.api(..., function() {
    if (++i < 3) foo();
    else i = 0;
  });
}

dib2 ★★★★★
()

я было хотел сказать, что в любом нормальном языке есть синхранизационные примитивы, но, видишь ли, JS это прикладной, узкопрофильный язык.

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

как альтернативный вариант, написать апплет на джаве или флеше, и дёргать из них функционал синхронизации.

anonymous
()

Это что б браузер тупил пока вконтакт не соизволит ответить? Умно, ничего не скажешь.

anonymous
()

помещать весь требующий синхроности с «запросом» в область синхроную с запросом.

либо принудительно синхронизироватся с . т.е. уходить в необлокирующее ожидание и просыватся регулярно - на вопрос можно ли идти дальше ибо запрос перекличил флаг_готовности

qulinxao ★★☆
()

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

Если точно так надо, по-тупому - запускай в обработчике следующий запрос. По-модному - promises всякие

Kalashnikov ★★★
()

i=2, data=data0

Хочешь i=0 — заверни именно эту i вместе с VK.api() в замыкание. Писать в continuation-passing стиле.

как корректно синхронизировать выполнение кода и запросов?

Если тебе не важно, в каком порядке будет обработка данных от твоего VK.api() — достаточно вышеупомянутого замыкания. Иначе — писать маааааленький диспетчер «процессов» (на деле — сопрограмм), с которым будешь работать этими замыканиями. В JS 1.7 есть yield, с которым всё это спокойно пишется, в остальных — обойдёшься. Но можешь писать на чём-то, компилирующемся в JS.

x3al ★★★★★
()
Ответ на: комментарий от dib2

Я же включил БРЕД МОДЕ. Конечно пример работать правильно не будет, тем более я жаваскрипт не знаю.

Но что-то мне подсказывает — твой тоже...

habamax ★★★
()

почитай про yield return в шарпе. Это некая state машина. И тебе нужно такую же огородить. В колбеке ВК-апи нужно инкрементировать шаг цикла и запускать следующую итерацию.

bvn13 ★★★★★
()
Ответ на: комментарий от x3al

спасибо. почитал, поличтал - что все жутчайшие костыли. я-то пишу простейший по логике скриптик с практической целью, не хотелось бы влезать в какие то дербри костылей на костылях.

дело в том, что, допустим, хочу получить данные о всех сообщениях всех тем в неком сообществе.

данные о темах отдаются по 100 шт. за раз, данные по сообщениям - тоже. т.е. алгоритм подразумевает несколько вложенных в друг друга циклов, выполнение последующего запроса зависит от результатов предыдущего.

блин, неужели это так проблематично реализовать :\

anonymous_sapiens ★★★★★
() автор топика
Ответ на: комментарий от anonymous_sapiens

Если предположить, что тебя устроит отправить следующий запрос только после того, как закончишь обрабатывать предыдущий — всё чуть проще. Но обычно это никого не устраивает. Поэтому велкам ту коллбэк хэлл либо то, что ты назвал костылями на костылях. Ну или писать на чём-то, компилирующемся в js.

x3al ★★★★★
()

Счетчик + стек отложенных вызовов.

https://github.com/caolan/async

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

Можно еще через промисы. Но лично я их не люблю. Умные слишком :)

Vit ★★★★★
()
Ответ на: комментарий от Vit

во, спасибо, кажется это то, что нужно.

иначе придется писать на джаве или питоне.

anonymous_sapiens ★★★★★
() автор топика

класическая ошибка, так заработает:

for (i=0; i<3; i++) {
	console.log ( "i=" + i );
	// запрос к серверу
        (function(){
	    VK.api (...,..., function (data) { console.log ( "i=" + i + ", data=" + data.response ) });
        })();
}

console.out ( "end of FOR" );

PS: Тред не читал

anthill
()
Последнее исправление: anthill (всего исправлений: 1)

В общем, поскольку стояла прикладная задача, оказалось ее удобней реализовать на Джаве.

anonymous_sapiens ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.