Как передать параметр в обратный вызов 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) функция была вызвана через некоторое время. Что я должен делать?


person Zeeshan Rang    schedule 27.07.2009    source источник
comment
немного больно комментировать такую ​​старую тему, но я просто должен предложить третью версию (которая, на мой взгляд, намного чище): setTimeout (postinsql.bind (null, topicId), 4000)   -  person Hobblin    schedule 13.09.2011
comment
здесь все ясно: w3schools.com/jsref/met_win_settimeout.asp   -  person Vladislav    schedule 14.10.2015


Ответы (29)


setTimeout(function() {
    postinsql(topicId);
}, 4000)

Вам нужно передать анонимную функцию в качестве параметра вместо строки, последний метод не должен работать даже в соответствии со спецификацией ECMAScript, но браузеры просто снисходительны. Это правильное решение, никогда не полагайтесь на передачу строки как «функции» при использовании setTimeout() или setInterval(), это медленнее, потому что его нужно оценивать, и это просто неправильно.

ОБНОВИТЬ:

Как сказал Хобблин в своих комментариях на вопрос, теперь вы можете передавать аргументы функции внутри setTimeout, используя Function.prototype.bind().

Пример:

setTimeout(postinsql.bind(null, topicId), 4000);
person meder omuraliev    schedule 27.07.2009
comment
Я помню, что мне потребовалось некоторое время, чтобы прийти к такому выводу. Иногда я думаю, что внутри объектов обычный вызов книги с "" не работает. Я до сих пор не знаю, почему ,,, но это тоже было мое решение - person Elzo Valugi; 28.07.2009
comment
window.setTimeout - это метод DOM, который не определяется спецификацией ECMAScript. Передача строки всегда работала в браузерах и является стандартом de facto - на самом деле возможность передачи объекта функции была добавлена ​​позже, в JavaScript 1.2 - это явно часть черновой спецификации HTML5 ( whatwg.org/ specs / web-apps / current-work / multipage /). Однако использование строки вместо объекта функции обычно считается плохим стилем, потому что это, по сути, форма отложенного eval(). - person Miles; 28.07.2009
comment
Eck - моя память сегодня не обслуживает ... setTimeout не определяется ES, да, но я не думаю, что это официальный метод DOM, который вы найдете в спецификации, просто метод DOM 0 (поддерживается браузерами с первых дней). - person meder omuraliev; 28.07.2009
comment
Это не входит в спецификацию W3C DOM, правильно. Так? Ваше утверждение, что последний метод не должен работать даже в соответствии со спецификацией ECMAScript, но браузеры просто снисходительны, по-прежнему неверно. - person Miles; 28.07.2009
comment
Да, как указано в setTimeout, не определенном ES в моем предыдущем комментарии, мой первый был неверным. - person meder omuraliev; 28.07.2009
comment
Я вижу много ответов на этот вопрос в дикой природе, используя просто цитату в виде строки. Хотя кажется, что люди говорят, что это должно сработать, я часто сталкиваюсь с ошибкой «не определено» с помощью этого метода, в то время как опция анонимной функции всегда работает. - person DA.; 29.04.2010
comment
Может кто-нибудь сказать мне, как бы вы очистили Timeout в этом примере? - person Neil; 21.02.2012
comment
var temp = setTimeout (функция () {postinsql (topicId);}, 4000); clearTimeout (темп); ?? - person Josh Mc; 19.06.2012
comment
Что произойдет, если topicId изменится после установки тайм-аута, но до вызова функции? - person pilau; 02.11.2012
comment
@pilau, это именно моя проблема: если переменные, используемые в анонимной функции, изменяются до тайм-аута (например, в цикле for), то они также изменятся внутри функции. Итак, в моем примере установка 5 разных тайм-аутов в цикле for фактически закончилась использованием одних и тех же переменных. Будьте осторожны при использовании этого ответа! - person Cristian; 08.05.2013
comment
Таким образом, этот метод не учитывает изменения значений перед вызовом функции - он всегда будет использовать исходное значение, переданное в setTimeout? - person pilau; 08.05.2013
comment
Вам нужно закрытие, чтобы все работало так, как задумано. - person Tom Auger; 18.05.2013
comment
@pilau, используя другое закрытие, поможет topicId = 12; функция postinsql (идентификатор темы) {console.log (идентификатор темы); } функция setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13; - person Halis Yılboğa; 23.12.2013
comment
@Miles Что касается вашего первого комментария, это технически не метод DOM, это метод WOM. - person SirPython; 10.02.2015
comment
@ HalisYılboğa Спасибо, друг, годы спустя я нашел ваш комментарий, и он мне помог. - person Jack Hales; 12.10.2017
comment
Если setTimeout(function() { postinsql(topicId); }, 4000) или setTimeout(function(topicId) { postinsql(topicId); }, 4000) не сработали. Используйте setTimeout(function(topicId) { postinsql(topicId); } (topicId), 4000) - person vee; 02.12.2018
comment
Почему вы прошли null за setTimeout(postinsql.bind(null, topicId), 4000); - person Shayan; 09.09.2020
comment
Даже лучше, чем метод bind, в настоящее время вы можете предоставить аргументы для setTimeout функция: setTimeout(postinsql, 4000, topicId). Хотя не работает в IE ниже 10 версии. - person Gras Double; 15.04.2021

В современных браузерах (например, IE11 и выше) setTimeout получает третий параметр, который отправляется как параметр внутренней функции в конце таймера.

Пример:

var hello = "Hello World";
setTimeout(alert, 1000, hello);

Подробнее:

person Fabio Phms    schedule 21.09.2011
comment
Я не уверен, почему этот ответ не был выбран как лучший. Конечно, использование анонимной функции работает, но если вы можете просто передать третий параметр в исходный вызов функции setTimeout ... почему бы и нет? - person Kris Schouw; 21.09.2011
comment
Потому что это не работает в версиях IE, которые все еще остаются в дикой природе. - person Aaron; 08.02.2012
comment
Также кажется, что это не официальная часть спецификации. Кроме того, w3cschools имеет третий параметр в качестве языка, на котором запускается функция. - person Kevin Schroeder; 15.05.2012
comment
Этот ответ фактически позволил мне передать объект события, а другие методы - нет. У меня уже была анонимная функция. - person Glenn Plas; 11.10.2012
comment
Гораздо лучший ответ. Если у вас есть код, который изменяет ваш параметр между вызовом setTimeout и фактическим выполнением анонимной функции, анонимная функция получит измененное значение, а не то, что было во время вызова setTimeout. например: for (var i = 0; i ‹100; i ++) {setTimeout (function () {console.write (i);}, 0); } это будет регистрировать 100 из 100 раз (проверено на FF). Текущий ответ помогает этого избежать. - person root; 14.12.2012
comment
Посмотрите ссылку в комментарии, там есть прокладка для старых версий IE. Это более правильный ответ, чем принятый ответ, который не сохраняет контекст, когда изначально был вызван тайм-аут. Обычно, когда вы передаете строку в settimeout, это потому, что вы пытаетесь сохранить текущее состояние, когда был вызван тайм-аут, а не состояние, когда он был запущен. - person wowo_999; 24.09.2013
comment
developer.mozilla.org/en/docs/Web/API/window. setTimeout имеет очень подробное объяснение этой функции. Вы можете найти правильный способ (работает в IE) для передачи параметров в анонимную функцию обратного вызова. - person raven; 22.08.2014
comment
Согласно developer.mozilla.org/es/docs/Web/API/ WindowTimers / setTimeout, аргументы обратного вызова для Internet Explorer поддерживаются только в версиях ›= 10, будьте осторожны, так как на многих сайтах ie8 и ie9 по-прежнему получают некоторую соответствующую долю. - person le0diaz; 03.06.2015
comment
Чтобы включить этот Internet Explorer ниже версии 10, используйте код из этого ответа: stackoverflow.com/a/12404562/2211053 - person Gavin; 15.02.2016
comment
Любой может дать мне простое объяснение, почему setTimeout (postinsql (topicId), 4000); не работает? - person Marek; 15.11.2017
comment
Лучший ответ. Работает как шарм. - person Skylin R; 24.04.2018
comment
@Marek - поскольку вы не передаете функцию postinsql в setTimeout, вы вызываете ее и передаете ее возвращаемое значение в setTimeout - person BryanGrezeszak; 17.06.2018
comment
О мой Бог! Я возился с этим в консоли, пока был на Medium, и они перезаписывают setTimeout с помощью настраиваемой функции, которая работает, но не передает дополнительные параметры. Думал, его удалили из Хрома без предупреждения что ли xD - person Mihail Malostanidis; 15.08.2018
comment
Это действительно должен быть принятый ответ. Ладно, не для старых фанатов браузеров, но определенно лучший вариант для современных браузеров. Сохранение исходного значения без каких-либо дополнительных манипуляций (лишнее закрытие, JSON.stringify-parse для скалярных значений и т. Д.) Параметров - величайшая помощь !! - person Jay Dadhania; 13.10.2019
comment
Вы можете удалить часть о современных браузерах, сегодня все основные браузеры поддерживают его (я тестировал это в Safari 12, так что и там он работает). - person Donald Duck; 06.08.2020
comment
Вот рабочий пример передачи нескольких параметров: setTimeout (function () {unMarkChosenCard (arguments [0], arguments [1]);}, 1000, selectedCardId, cardsOnTableInfo [i]); - person Shimon Agassi; 01.07.2021

После некоторого исследования и тестирования единственная правильная реализация:

setTimeout(yourFunctionReference, 4000, param1, param2, paramN);

setTimeout передаст все дополнительные параметры вашей функции, чтобы их можно было обработать там.

Анонимная функция может работать для очень простых вещей, но в экземпляре объекта, где вы должны использовать "this", нет способа заставить ее работать. Любая анонимная функция изменит "this", чтобы указать на окно, поэтому вы потеряете ссылку на объект.

person Jiri Vetyska    schedule 30.10.2012
comment
С грустью в душе должен сообщить: в Internet Explorer это не работает. : / Все дополнительные параметры не определены. - person Amalgovinus; 24.04.2013
comment
внутри экземпляра объекта, где вы должны это использовать, нет способа заставить его работать. - не правда. Вы можете заставить this справочник работать, даже не используя bind (поддерживается начиная с IE9). Вы просто передаете следующую анонимную функцию: function() { someObject.someMethod() }. - person Myrne Stol; 29.05.2013
comment
Я просто использую var that = this; setTimeout( function() { that.foo(); }, 1000); - person Ed Williams; 07.06.2013
comment
Это правильно, и это указано в HTML5. whatwg.org/specs/ web-apps / current-work / multipage / - person Garrett; 13.01.2014
comment
Это точно такой же ответ, что и Фабио. - person Dan Dascalescu; 17.04.2015
comment
Согласно developer.mozilla.org/es/docs/Web/API/ WindowTimers / setTimeout, аргументы обратного вызова для Internet Explorer поддерживаются только в версиях ›= 10, будьте осторожны, так как на многих сайтах ie8 и ie9 по-прежнему получают некоторую соответствующую долю. - person le0diaz; 03.06.2015

Это очень старый вопрос с уже "правильным" ответом, но я подумал, что упомянул бы еще один подход, о котором здесь никто не упоминал. Это скопировано и вставлено из превосходной библиотеки подчеркивания:

_.delay = function(func, wait) {
  var args = slice.call(arguments, 2);
  return setTimeout(function(){ return func.apply(null, args); }, wait);
};

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

Вот скрипка, где вы можете понять, что я имею в виду.

person David Meister    schedule 18.12.2012
comment
Этот ответ действительно работает, но, похоже, у вас есть какая-то библиотека, которой нет у меня. Вот небольшое исправление, чтобы это работало: вместо slice.call используйте Array.prototype.slice.call (arguments, 2) - person Melanie; 03.10.2013
comment
@ Мелани какая-нибудь библиотека? В ответе я сказал, что это библиотека подчеркивания - underscorejs.org. Но да, Array.prototype.slice имеет псевдоним для срезания внутри этой библиотеки, поэтому вам придется сделать это самостоятельно, если вы его не используете, хорошее место :) - person David Meister; 04.10.2013

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

Метод 1

Используйте forEach и Object.keys в соответствии с Сукимы. предложение:

var testObject = {
    prop1: 'test1',
    prop2: 'test2',
    prop3: 'test3'
};

Object.keys(testObject).forEach(function(propertyName, i) {
    setTimeout(function() {
        console.log(testObject[propertyName]);
    }, i * 1000);
});

Я рекомендую этот метод.

Способ 2

Используйте bind:

var i = 0;
for (var propertyName in testObject) {
    setTimeout(function(propertyName) {
        console.log(testObject[propertyName]);
    }.bind(this, propertyName), i++ * 1000);
}

JSFiddle: http://jsfiddle.net/MsBkW/

Способ 3

Или, если вы не можете использовать forEach или bind, используйте IIFE:

var i = 0;
for (var propertyName in testObject) {
    setTimeout((function(propertyName) {
        return function() {
            console.log(testObject[propertyName]);
        };
    })(propertyName), i++ * 1000);
}

Метод 4

Но если вас не волнует IE ‹10, вы можете использовать предложение Фабио :

var i = 0;
for (var propertyName in testObject) {
    setTimeout(function(propertyName) {
        console.log(testObject[propertyName]);
    }, i++ * 1000, propertyName);
}

Метод 5 (ES6)

Используйте переменную с областью видимости блока:

let i = 0;
for (let propertyName in testObject) {
    setTimeout(() => console.log(testObject[propertyName]), i++ * 1000);
}

Хотя я все же рекомендую использовать Object.keys с forEach в ES6.

person David Sherret    schedule 09.07.2013
comment
Примечание. .bind не будет работать в IE8 и ниже [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/]. В итоге я использовал решение Schien: stackoverflow.com/a/21213723/1876899 - person cjspurgeon; 22.04.2014
comment
Если вы находитесь в среде, которая использует bind, то вы также находитесь в среде, которая предлагает Object.keys и forEach. Вы можете потерять цикл for и получить бесплатную (как в случае с двумя зайцами, свободными от ресурсов, а не без ресурсов) область видимости функции в процессе. - person Sukima; 08.07.2014
comment
@David Sherret, если вы не использовали его раньше, обязательно посетите async библиотеку (github.com/caolan/ асинхронный). Мы широко используем его в Sails и добились отличных результатов за последние 2 года. Он предоставляет методы как в параллельном, так и в последовательном режиме для асинхронных forEach, map, reduce и т. Д. - person mikermcneil; 23.10.2015

Хобблин уже прокомментировал этот вопрос, но это действительно должен быть ответ!

Использование 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

person dain    schedule 25.03.2013
comment
контекст this можно передать с первым аргументом bind setTimeout(postinsql.bind(this, topicId), 4000); - person Giuseppe Galano; 11.12.2013
comment
@GiuseppeGalano полностью, я упомянул об этом в своем ответе, но в этом примере это не нужно :) - person dain; 15.12.2013
comment
Удивительно, как многие скрывают частичные приложения с помощью bind. Это действительно делает код читабельным. - person Sukima; 08.07.2014
comment
bind () поддерживается только в IE9 +, поэтому этот подход не будет работать для ‹IE9 - person Sanjeev; 06.08.2014
comment
@Sanjeev Используйте прокладку ES5, чтобы она работала в более раннем IE: github.com/es-shims/es5 -shim - person gregers; 04.03.2016

Некоторые ответы верны, но запутаны.

Я снова отвечаю на это, 4 года спустя, потому что я все еще сталкиваюсь с чрезмерно сложным кодом, чтобы решить именно этот вопрос. ЕСТЬ элегантное решение.

Прежде всего, не передавайте строку в качестве первого параметра при вызове setTimeout, потому что он эффективно вызывает вызов медленной функции «eval».

Так как же передать параметр функции тайм-аута? Используя закрытие:

settopic=function(topicid){
  setTimeout(function(){
    //thanks to closure, topicid is visible here
    postinsql(topicid);
  },4000);
}

...
if (xhr.readyState==4){
  settopic(xhr.responseText);
}

Некоторые предлагают использовать анонимную функцию при вызове функции тайм-аута:

if (xhr.readyState==4){
  setTimeout(function(){
    settopic(xhr.responseText);
  },4000);
}

Синтаксис работает. Но к моменту вызова settopic, то есть через 4 секунды, объект XHR может быть другим. Поэтому важно предварительно связать переменные.

person Schien    schedule 19.01.2014
comment
+1 за читабельное решение, немного отличающееся от моего. Пока у вас есть setTimeout внутри функции settopic, у меня есть функция fDelayed (ваша settopic) внутри функции setTimeout. - person Dominic; 20.01.2014

Вы можете передать параметр функции обратного вызова setTimeout как:

setTimeout (функция, миллисекунды, параметр1, параметр2, ...)

eg.

function myFunction() {
  setTimeout(alertMsg, 3000, "Hello");
}

function alertMsg(message) {
    alert(message)
}
person Jatin Verma    schedule 28.05.2019
comment
Может ли кто-нибудь сказать мне, почему этот ответ не является предпочтительным? это самый простой способ на мой взгляд! Так просто, как setTimeout( (p) => { console.log(p); }, 1000, "hi" ); - person Mazhar Zandsalimi; 20.10.2019
comment
Ага! Это должен быть принятый ответ. Из MDN: developer.mozilla.org/en-US/docs / Web / API / - person Han; 26.12.2019

Я знаю, что прошло 10 лет с тех пор, как этот вопрос был задан, но все же, если вы прокрутили до этого места, я предполагаю, что вы все еще сталкиваетесь с какой-то проблемой. Решение Медера Омуралиева является самым простым и может помочь большинству из нас, но для тех, кто не хочет иметь никаких привязок, вот оно:

  1. Используйте Param для setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Использовать выражение немедленно вызываемой функции (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Решение вопроса
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}
person Alpesh Patil    schedule 02.12.2019

Мой ответ:

setTimeout((function(topicId) {
  return function() {
    postinsql(topicId);
  };
})(topicId), 4000);

Объяснение:

Созданная анонимная функция возвращает другую анонимную функцию. Эта функция имеет доступ к первоначально переданному topicId, поэтому она не будет делать ошибки. Первая анонимная функция вызывается немедленно, передавая topicId, поэтому зарегистрированная функция с задержкой имеет доступ к topicId во время вызова через закрытие.

OR

Это в основном преобразуется в:

setTimeout(function() {
  postinsql(topicId); // topicId inside higher scope (passed to returning function)
}, 4000);

РЕДАКТИРОВАТЬ: я видел тот же ответ, поэтому посмотрите его. Но я не украл его ответ! Я просто забыл посмотреть. Прочтите объяснение и посмотрите, поможет ли оно понять код.

person Community    schedule 01.06.2016
comment
Это лучший ответ. Многие из этих решений даже не учитывают тайм-аут. Однако почему вы заключаете первую анонимную функцию в скобки? Я не думаю, что они необходимы для этого. - person Robert Henderson; 02.03.2018
comment
это лучший ответ ????, но пришлось сделать клон, потому что, когда значения вроде topicId изменяются, значение тайм-аута также изменяется. Клон исправил это - person pariola; 05.07.2018

Заменять

 setTimeout("postinsql(topicId)", 4000);

с участием

 setTimeout("postinsql(" + topicId + ")", 4000);

или еще лучше, замените строковое выражение анонимной функцией

 setTimeout(function () { postinsql(topicId); }, 4000);

РЕДАКТИРОВАТЬ:

Комментарий Браунстоуна неверен, он будет работать так, как задумано, как показано, запустив его в консоли Firebug.

(function() {
  function postinsql(id) {
    console.log(id);
  }
  var topicId = 3
  window.setTimeout("postinsql(" + topicId + ")",4000); // outputs 3 after 4 seconds
})();

Обратите внимание, что я согласен с другими, что вам следует избегать передачи строки в setTimeout, поскольку это вызовет eval() в строке и вместо этого передаст функцию.

person Russ Cam    schedule 27.07.2009
comment
Это не сработает, потому что результат postinsql (topicId) будет выполнен setTimeout. Вам нужно обернуть его функцией, как в первом ответе, или использовать помощник, такой как Prototype .curry () - setTimeout (postinsql.curry (topidId), 4000); - person shuckster; 28.07.2009
comment
@brownstone: Это неверно. Строка будет оценена, когда сработает тайм-аут. - person Miles; 28.07.2009

Самое простое кроссбраузерное решение для поддержки параметров в setTimeout:

setTimeout(function() {
    postinsql(topicId);
}, 4000)

Если вы не против не поддерживать IE 9 и ниже:

setTimeout(postinsql, 4000, topicId);

setTimeout совместимость с браузером рабочего стола

setTimeout Совместимость с мобильным браузером

https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout

person Community    schedule 02.06.2015

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

Я думаю, что довольно удобочитаемый способ добиться этого - передать topicId функции, которая, в свою очередь, использует аргумент для внутренней ссылки на идентификатор темы. Это значение не изменится, даже если topicId снаружи изменится вскоре после этого.

var topicId = xmlhttp.responseText;
var fDelayed = function(tid) {
  return function() {
    postinsql(tid);
  };
}
setTimeout(fDelayed(topicId),4000);

или коротко:

var topicId = xmlhttp.responseText;
setTimeout(function(tid) {
  return function() { postinsql(tid); };
}(topicId), 4000);
person Dominic    schedule 20.11.2013

Ответ Дэвида Мейстера, похоже, касается параметров, которые могут измениться сразу после вызова setTimeout (), но до вызова анонимной функции. Но это слишком громоздко и не очень очевидно. Я обнаружил элегантный способ сделать почти то же самое с помощью IIFE (немедленно вызываемое выражение функции).

В приведенном ниже примере переменная currentList передается в IIFE, который сохраняет ее при закрытии, пока не будет вызвана отложенная функция. Даже если переменная currentList изменится сразу после показанного кода, setInterval() поступит правильно.

Без этой техники IIFE функция setTimeout() определенно будет вызываться для каждого h2 элемента в DOM, но все эти вызовы будут видеть только текстовое значение последнего h2 элемента.

<script>
  // Wait for the document to load.
  $(document).ready(function() {
  $("h2").each(function (index) {

    currentList = $(this).text();

    (function (param1, param2) {
        setTimeout(function() {
            $("span").text(param1 + ' : ' + param2 );
        }, param1 * 1000);

    })(index, currentList);
  });
</script>
person Gurjeet Singh    schedule 16.04.2014

В общем, если вам нужно передать функцию как обратный вызов с определенными параметрами, вы можете использовать функции более высокого порядка. Это довольно элегантно с ES6:

const someFunction = (params) => () => {
  //do whatever
};

setTimeout(someFunction(params), 1000);

Или, если someFunction - первый заказ:

setTimeout(() => someFunction(params), 1000); 
person John Hartman    schedule 08.02.2018
comment
это очень несовместимо - person user151496; 07.03.2018
comment
Действительно элегантно! Спасибо - person Velojet; 13.07.2019

Обратите внимание, что причина, по которой topicId был «не определен» в сообщении об ошибке, заключается в том, что он существовал как локальная переменная при выполнении setTimeout, но не при отложенном вызове postinsql. На время жизни переменной особенно важно обращать внимание, особенно когда вы пытаетесь передать что-то вроде "this" в качестве ссылки на объект.

Я слышал, что вы можете передать topicId в качестве третьего параметра функции setTimeout. Дается не так много подробностей, но у меня достаточно информации, чтобы заставить его работать, и он успешно работает в Safari. Я не знаю, что они имеют в виду под «миллисекундной ошибкой». Посмотрите здесь:

http://www.howtocreate.co.uk/tutorials/javascript/timers

person billy    schedule 05.12.2010

Как я решил этот этап?

Просто так :

setTimeout((function(_deepFunction ,_deepData){
    var _deepResultFunction = function _deepResultFunction(){
          _deepFunction(_deepData);
    };
    return _deepResultFunction;
})(fromOuterFunction, fromOuterData ) , 1000  );

setTimeout ждет ссылки на функцию, поэтому я создал ее в закрытии, которое интерпретирует мои данные и возвращает функцию с хорошим экземпляром моих данных!

Возможно, вы можете улучшить эту часть:

_deepFunction(_deepData);

// change to something like :
_deepFunction.apply(contextFromParams , args); 

Я тестировал его на Chrome, Firefox и IE, и он работает хорошо, я не знаю о производительности, но мне нужно, чтобы он работал.

образец теста:

myDelay_function = function(fn , params , ctxt , _time){
setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.call(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// the function to be used :
myFunc = function(param){ console.log(param + this.name) }
// note that we call this.name

// a context object :
myObjet = {
    id : "myId" , 
    name : "myName"
}

// setting a parmeter
myParamter = "I am the outer parameter : ";

//and now let's make the call :
myDelay_function(myFunc , myParamter  , myObjet , 1000)

// this will produce this result on the console line :
// I am the outer parameter : myName

Возможно, вы можете изменить подпись, чтобы сделать ее более подходящей:

myNass_setTimeOut = function (fn , _time , params , ctxt ){
return setTimeout((function(_deepFunction ,_deepData, _deepCtxt){
            var _deepResultFunction = function _deepResultFunction(){
                //_deepFunction(_deepData);
                _deepFunction.apply(  _deepCtxt , _deepData);
            };
        return _deepResultFunction;
    })(fn , params , ctxt)
, _time) 
};

// and try again :
for(var i=0; i<10; i++){
   myNass_setTimeOut(console.log ,1000 , [i] , console)
}

И наконец, чтобы ответить на исходный вопрос:

 myNass_setTimeOut( postinsql, 4000, topicId );

Надеюсь, это поможет!

ps: извините, но английский это не мой родной язык!

person Anonymous0day    schedule 28.05.2013
comment
Это слишком сложно по сравнению с другими ответами. - person Dan Dascalescu; 17.04.2015

это работает во всех браузерах (IE - чудак)

setTimeout( (function(x) {
return function() {
        postinsql(x);
    };
})(topicId) , 4000);
person user3756459    schedule 19.06.2014

если вы хотите передать переменную в качестве параметра, попробуйте это

если требование - это функция, а var as parmas, попробуйте это

setTimeout((param1,param2) => { 
     alert(param1 + param2);
     postinsql(topicId);
},2000,'msg1', 'msg2')

if requirement is only variables as a params then try this

setTimeout((param1,param2) => { alert(param1 + param2) },2000,'msg1', 'msg2')

Вы можете попробовать это с ES5 и ES6

person mad Man    schedule 27.12.2018

setTimeout является частью модели DOM, определенной WHAT WG.

https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html

Вам нужен следующий метод: -

handle = self.setTimeout( handler [, timeout [, arguments... ] ] )

Планирует тайм-аут для запуска обработчика после тайм-аута в миллисекундах. Любые аргументы передаются непосредственно обработчику.

setTimeout(postinsql, 4000, topicId);

Судя по всему, в IE10 поддерживаются дополнительные аргументы. В качестве альтернативы вы можете использовать setTimeout(postinsql.bind(null, topicId), 4000);, однако передача дополнительных аргументов проще и предпочтительнее.

Исторический факт: во времена VBScript в JScript третьим параметром setTimeout был язык в виде строки со значением по умолчанию «JScript», но с возможностью использования «VBScript». https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)

person Garrett    schedule 27.11.2019

Вы можете попробовать по умолчанию функцию «apply ()» примерно так, вы можете передать большее количество аргументов в соответствии с вашими требованиями в массиве

function postinsql(topicId)
{
  //alert(topicId);
}
setTimeout(
       postinsql.apply(window,["mytopic"])
,500);
person Vishnu Prasanth G    schedule 06.06.2018

Вам нужно удалить кавычки из вашего setTimeOut вызова функции следующим образом:

setTimeout(postinsql(topicId),4000);
person Ghanshyam Sharma    schedule 12.03.2020

@Jiri Vetyska благодарит за сообщение, но в вашем примере что-то не так. Мне нужно было передать цель, которая зависла (это), функции тайм-аута, и я попробовал ваш подход. Тестировал в IE9 - не работает. Я также провел некоторое исследование, и, похоже, как указано здесь, третий параметр - это язык сценария. быть использованным. Никаких упоминаний о дополнительных параметрах.

Итак, я последовал за ответом @meder и решил свою проблему с помощью этого кода:

$('.targetItemClass').hover(ItemHoverIn, ItemHoverOut);

function ItemHoverIn() {
 //some code here
}

function ItemHoverOut() {
    var THIS = this;
    setTimeout(
        function () { ItemHoverOut_timeout(THIS); },
        100
    );
}
function ItemHoverOut_timeout(target) {
    //do something with target which is hovered out
}

Надеюсь, это будет полезно для кого-то еще.

person Vladislav    schedule 27.02.2013

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

Мы можем попробовать использовать рекурсию вот так:

var i = 0;
var hellos = ["Hello World1!", "Hello World2!", "Hello World3!", "Hello World4!", "Hello World5!"];

if(hellos.length > 0) timeout();

function timeout() {                
    document.write('<p>' + hellos[i] + '<p>');
    i++;
    if (i < hellos.length)
        setTimeout(timeout, 500);
}

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

person Vakhtang Tevdorashvili    schedule 23.12.2013

// Это три очень простых и лаконичных ответа:

function fun() {
    console.log(this.prop1, this.prop2, this.prop3);
}

let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };

let bound = fun.bind(obj);

setTimeout(bound, 3000);

 // or

function funOut(par1, par2, par3) {

  return function() { 

    console.log(par1, par2, par3);

  }
};

setTimeout(funOut('one', 'two', 'three'), 5000);

 // or

let funny = function(a, b, c) { console.log(a, b, c); };

setTimeout(funny, 2000, 'hello', 'worldly', 'people');
person Rich    schedule 23.04.2019

Я думаю, ты хочешь:

setTimeout("postinsql(" + topicId + ")", 4000);
person Community    schedule 27.07.2009
comment
Я встречал случаи, когда это просто не работало (всегда приводило к ошибке «функция не определена»), но использование анонимной функции действительно работает. Что расстраивает, учитывая, что все, кажется, говорят, что приведенный выше синтаксис всегда должен работать. (может быть, jQuery каким-то образом мешает методу «цитата как строка»?) - person DA.; 29.04.2010
comment
Предположим, topicId - это функция ... Или объект. Это не сработает! - person Serafeim; 23.11.2011
comment
Если вы действительно хотите использовать этот метод, используйте JSON.stringify для обычных объектов и массивов, а затем используйте JSON.parse внутри функции. Однако все поведение будет потеряно, если у объекта есть методы. - person DarthCadeus; 20.12.2018

// Это три очень простых и лаконичных ответа:

function fun() {
    console.log(this.prop1, this.prop2, this.prop3);
}

let obj = { prop1: 'one', prop2: 'two', prop3: 'three' };

let bound = fun.bind(obj);

setTimeout(bound, 3000);

 // or

function funOut(par1, par2, par3) {

  return function() { 

    console.log(par1, par2, par3);

  }
};

setTimeout(funOut('one', 'two', 'three'), 5000);

 // or

let funny = function(a, b, c) { console.log(a, b, c); };

setTimeout(funny, 2000, 'hello', 'worldly', 'people');
person user11385739    schedule 19.04.2019

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

var x = 3, y = 4;

setTimeout(function(arg1, arg2) { 
      delayedSum(arg1, arg2);
}(x, y), 1000);

function delayedSum(param1, param2) {
     alert(param1 + param2); // 7
}
person SridharKritha    schedule 13.02.2020
comment
Это не работает, потому что функция вызывается немедленно, как она определена, она не использует значение тайм-аута. Не используйте этот метод. - person qJake; 19.08.2020

person    schedule
comment
Пожалуйста, не публикуйте только код в качестве ответа, но также объясните, что делает ваш код и как он решает проблему вопроса. Ответы с объяснением обычно более полезны и качественнее, и с большей вероятностью получат положительные отзывы. - person Tyler2P; 15.07.2021
comment
Я добавил объяснение в комментариях для двух разных случаев. И оба случая позволяют принимать параметры (аргументы функции) в любом порядке, так что это краткое решение проблемы. - person AnonymousUser; 16.07.2021