Javascript setInterval: перекрываются ли вызовы?

Предположим, что у меня есть setInterval(PostToServer, 1000);. Функция PostToServer делает запись ajax, которая может занимать больше секунды. Итак, что происходит потом: второй вызов выполняется, пока первый не закончил или ожидающий конец вызова, прежде чем создавать новый?

Ответ 1

Накладки перекрываются.

setInterval гарантирует, что функции выполняются регулярно, не дожидаясь предыдущего результата.

Если вы хотите дождаться ответа, измените метод интервалов на poller. Когда прошло время И сервер уже ответил, запросите еще раз.

Поскольку ответ сервера не изменится слишком сильно сразу после ответа, вы также можете добавить обработчик setTimeout в функцию обратного вызова вашего метода AJAX.

Ответ 2

Javascript является однопоточным (за исключением веб-работников HTML5, которые не участвуют в этой проблеме) с очередью событий. Последующий вызов из setInterval() никогда не запустится до тех пор, пока не будет выполнен предыдущий вызов. Только один может быть активным одновременно.

Когда время вашего интервала происходит, внутри JS-двигателя запускается таймер, и событие добавляется в очередь событий javascript. Когда текущий исполняемый поток выполнения JS завершается (а не раньше), JS-движок отправляется и выбирает следующее событие из очереди событий и запускает этот поток выполнения JS. Таким образом, два пути выполнения в JS никогда не будут перекрываться или продолжаться в одно и то же время. Таким образом, два вызова функций из setInterval() никогда не будут перекрываться. Второй не запускается до тех пор, пока не будет выполнен первый.

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

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

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

Ответ 3

Да, он перекрывается. Вы можете использовать setTimeout в функции PostToServer, чтобы убедиться, что он не перекрывается, но проблема в том, что он запускает запрос, а затем ждет 1s, а затем снова запускает запрос. Поэтому он не запускается каждую секунду точно.

Для получения дополнительной информации см. это видео Paul Irish: http://youtu.be/i_qE1iAmjFg?t=7m46s