#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть функция для обновления графиков на странице. Идея в том, что он постоянно зацикливается и обновляет вызываемую переменную salt
. Переменные определены в отдельном файле и называются path
, displayTimeFrom
, selectedTimeRangeType
и target
. Вот код цикла, который также реагирует на изменения в графическом интерфейсе:
$(function () {
refreshGraphs();
});
var refreshGraphs = function () {
d = new Date();
var graphiteUrl = graphs.path "render/?_salt" d.getTime()
"amp;from=-" graphs.displayTimeFrom
graphs.selectedTimeRangeType
"amp;minXStep=0"
"amp;until=nowamp;height=800amp;";
$('#graph-middle').prop("src", graphiteUrl graphs.target);
setIntervalAndExecute(refreshGraphs, 30000); // refresh every 30000 milliseconds aka every 30 seconds
// Execute immediately and after the interval (setInterval only starts after certain amount of time)
function setIntervalAndExecute(fn, t) {
fn();
return (setInterval(fn, t));
}
// Change graph to chosen value
$('#graph-middle').on('click', '#displayTimeFrom', function () {
graphs.displayTimeFrom = $(this).text();
refreshGraphs();
});
$('#graph-middle').on('click', '#selectedTimeRangeType', function () {
graphs.selectedTimeRangeType = $(this).text();
refreshGraphs();
});
};
Когда я запускаю его, он говорит "too much recursion"
. Почему это так и как я могу это решить?
Комментарии:
1. Я отредактировал свой ответ. пожалуйста, проверьте
Ответ №1:
Ваша refreshGraphs()
функция вызывает себя немедленно (через setIntervalAndExecute()
) при каждом запуске.
Комментарии:
1. Проблема не в этом. Эта рекурсия разрешена, поскольку ожидание составляет 30 секунд. Проблема заключалась в привязке jQuery в функции refreshgraphs . Как только я поместил их в анонимную функцию сверху (документ готов), все было в порядке.
2. @user2609980: Нет;
fn()
вызов тоже запускает его немедленно.3. Ну, это не проблема, когда я помещаю код jQuery в
$(function()
.4. Я снова смотрю на код. И теперь я вижу, что вы, должно быть, правы. Переместив
setIntervalAndExecute
в$function()
и за пределыrefreshGraphs
, я думаю, я убедился, что немедленное и рекурсивное выполнениеfn()
вызывается только один раз (сейчас нет доступа к коду, поэтому не уверен, каким именно было решение). Я посмотрю позже. Тем не менее, код отлично работает месяцами подряд (т. Е. Он обновляет графики каждые 30 секунд …). Мне интересно, вызывает ли jQueryrefreshGraphs()
какой-то сложный цикл, который просто работает.
Ответ №2:
Следует отметить две вещи:
1. Вы вызываете refreshGraphs()
рекурсивно.
2. Вы поместили click
обработчики в refreshGraphs()
функцию.
Поэтому всякий раз, когда это refreshGraphs()
вызывается, оно click
снова связывает события, не отменяя привязку предыдущего. Вам нужно либо отменить привязку предыдущего, либо вы можете поместить их $(function () {})
.
Попробуйте любой из них.
$(function () {
refreshGraphs();
// Change graph to chosen value
$('#graph-middle').on('click', '#displayTimeFrom', function () {
graphs.displayTimeFrom = $(this).text();
refreshGraphs();
});
$('#graph-middle').on('click', '#selectedTimeRangeType', function () {
graphs.selectedTimeRangeType = $(this).text();
refreshGraphs();
});
});
var refreshGraphs = function () {
d = new Date();
var graphiteUrl = graphs.path "render/?_salt" d.getTime()
"amp;from=-" graphs.displayTimeFrom
graphs.selectedTimeRangeType
"amp;minXStep=0"
"amp;until=nowamp;height=800amp;";
$('#graph-middle').prop("src", graphiteUrl graphs.target);
setIntervalAndExecute(refreshGraphs, 30000); // refresh every 30000 milliseconds aka every 30 seconds
// Execute immediately and after the interval (setInterval only starts after certain amount of time)
function setIntervalAndExecute(fn, t) {
fn();
return (setInterval(fn, t));
}
};
Или
$(function () {
refreshGraphs();
});
var refreshGraphs = function () {
d = new Date();
var graphiteUrl = graphs.path "render/?_salt" d.getTime()
"amp;from=-" graphs.displayTimeFrom
graphs.selectedTimeRangeType
"amp;minXStep=0"
"amp;until=nowamp;height=800amp;";
$('#graph-middle').prop("src", graphiteUrl graphs.target);
setIntervalAndExecute(refreshGraphs, 30000); // refresh every 30000 milliseconds aka every 30 seconds
// Execute immediately and after the interval (setInterval only starts after certain amount of time)
function setIntervalAndExecute(fn, t) {
fn();
return (setInterval(fn, t));
}
// Change graph to chosen value
$('#graph-middle').off('click').on('click', '#displayTimeFrom', function () {
graphs.displayTimeFrom = $(this).text();
refreshGraphs();
});
$('#graph-middle').off('click').on('click', '#selectedTimeRangeType', function () {
graphs.selectedTimeRangeType = $(this).text();
refreshGraphs();
});
};
Комментарии:
1. Лучше объяснить, что вы изменили и почему вы это изменили, а не оставлять OP в недоумении.
Ответ №3:
Решение состоит в том, чтобы вызвать jQuery в анонимной функции вместо пространства имен refreshGraps . Проблема решена.