Как передать параметр в колбек setTimeout()?
У меня есть код на JavaScript, который выглядит следующим образом:
function statechangedPostQuestion() {
//alert("statechangedPostQuestion");
if (xmlhttp.readyState == 4) {
var topicId = xmlhttp.responseText;
setTimeout("postinsql(topicId)", 4000);
}
}
function postinsql(topicId) {
//alert(topicId);
}
Я получаю ошибку о том, что topicId
не определен. Всё работало до того, как я добавил функцию setTimeout()
.
Я хочу, чтобы моя функция postinsql(topicId)
вызывалась через некоторое время. Что мне нужно сделать?
5 ответ(ов)
После проведения исследований и тестирования, единственным правильным способом является:
setTimeout(yourFunctionReference, 4000, param1, param2, paramN);
Функция setTimeout
передаст все дополнительные параметры вашей функции, чтобы их можно было обработать внутри нее.
Анонимная функция может работать для очень простых задач, но в случае использования внутри экземпляра объекта, где необходимо использовать this
, она не подойдет. Любая анонимная функция изменит значение this
, указывая на глобальный объект (window), в результате вы потеряете ссылку на ваш объект.
Вы можете передать параметры в функцию обратного вызова setTimeout
следующим образом:
setTimeout(функция, миллисекунды, параметр1, параметр2, ...)
Пример:
function myFunction() {
setTimeout(alertMsg, 3000, "Hello");
}
function alertMsg(message) {
alert(message);
}
В этом примере функция alertMsg
будет вызвана через 3000 миллисекунд (или 3 секунды) с параметром "Hello". Это позволяет удобно передавать данные в функцию, вызываемую через setTimeout
.
Hobblin уже прокомментировал это в вопросе, но это действительно должно быть ответом!
Использование Function.prototype.bind()
– это самый чистый и гибкий способ сделать это (с дополнительным бонусом возможности установить контекст this
):
setTimeout(postinsql.bind(null, topicId), 4000);
Для получения дополнительной информации посмотрите на эти ссылки MDN:
https://developer.mozilla.org/en/docs/DOM/window.setTimeout#highlighter_547041
https://developer.mozilla.org/en/docs/JavaScript/Reference/Global_Objects/Function/bind#With_setTimeout
Я знаю, что с момента, когда этот вопрос был задан, прошло уже 10 лет, но если вы дошли до этого места, я предполагаю, что вы все еще сталкиваетесь с некоторыми проблемами. Решение, предложенное Мелером Омуралиевым, является самым простым и может помочь большинству из нас, но для тех, кто не хочет использовать никаких привязок, вот альтернативные варианты:
- Используйте параметр для setTimeout:
setTimeout(function(p){
// p == param1
}, 3000, param1);
- Используйте немедленно вызываемое функциональное выражение (IIFE):
let param1 = 'demon';
setTimeout(function(p){
// p == 'demon'
}, 2000, (function(){
return param1;
})());
- Пример решения задания:
function statechangedPostQuestion() {
//alert("statechangedPostQuestion");
if (xmlhttp.readyState == 4) {
setTimeout(postinsql, 4000, (function(){
return xmlhttp.responseText;
})());
}
}
function postinsql(topicId) {
//alert(topicId);
}
Надеюсь, это поможет решить вашу задачу! Если у вас есть дополнительные вопросы, не стесняйтесь спрашивать.
Чтобы заменить строку
setTimeout("postinsql(topicId)", 4000);
на
setTimeout("postinsql(" + topicId + ")", 4000);
или лучше, заменить строковое выражение на анонимную функцию,
setTimeout(function () { postinsql(topicId); }, 4000);
ИЗМЕНЕНИЕ:
Комментарий Brownstone неверен, это будет работать как задумано, что можно продемонстрировать, выполнив следующий код в консоли Firebug:
(function() {
function postinsql(id) {
console.log(id);
}
var topicId = 3;
window.setTimeout("postinsql(" + topicId + ")", 4000); // выводит 3 через 4 секунды
})();
Обратите внимание, что я согласен с другими, что стоит избегать передачи строки в setTimeout
, так как это вызовет eval()
на строке, вместо этого лучше передавать функцию.
Установка значения по умолчанию для параметра функции в JavaScript
Как получить правильный `this` внутри колбэка?
В чем разница между String.slice и String.substring?
Существует ли ссылка на "последнюю" библиотеку jQuery в Google APIs?
Как создать диалог с кнопками "Ок" и "Отмена"