Как я могу передать параметр в функцию обратного вызова setTimeout ()?

828

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

Зеешан Ранг
источник
75
Больно комментировать такую ​​старую тему, но я просто должен предложить третью версию (которая, на мой взгляд, намного чище): setTimeout (postinsql.bind (null, topicId), 4000)
Хобблин,
14
@Hobblin: почему было бы больно ставить рекорд прямо? Разве это не повредит другим больше, чтобы сесть на этот популярный вопрос и увидеть старый, обескураженный стиль вызова?
Дан Даскалеску
2
здесь все ясно: w3schools.com/jsref/met_win_settimeout.asp
Владислав
@dbliss Мое предложение уже было упомянуто в нескольких ответах и ​​добавлено в качестве ответа здесь: stackoverflow.com/a/15620038/287130 Но я рад, что мое предложение ценится;)
Хобблин
@ Хобблин, спасибо, что указал на это. Я пролистал, ища ответ, опубликованный вами, и пропустил это.
dbliss

Ответы:

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

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

ОБНОВИТЬ:

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

Пример:

setTimeout(postinsql.bind(null, topicId), 4000);
медер омуралиев
источник
30
window.setTimeoutявляется методом DOM и как таковой не определен спецификацией ECMAScript. Передача строки всегда работала в браузерах и является стандартом де-факто - фактически, возможность передачи функционального объекта была добавлена ​​позже, с JavaScript 1.2 - она ​​явно является частью проекта спецификации HTML5 ( whatwg.org/specs/web -apps / current-work / multipage /… ). Однако использование строки вместо функционального объекта обычно считается плохим стилем, потому что это, по сути, форма с задержкой eval().
Майлз
2
var temp = setTimeout (function () {postinsql (topicId);}, 4000); clearTimeout (температура); ??
Джош Мак
12
Что произойдет, если topicId будет изменен после установки времени ожидания, но до вызова функции?
плов
22
@pilau - это как раз моя проблема: если переменные, используемые в анонимной функции, изменятся до истечения времени ожидания (например, в цикле for), то это также изменится внутри функции. Так что в моем примере установка 5 различных таймаутов в цикле for фактически заканчивалась использованием одинаковых переменных. Будьте осторожны при использовании этого ответа!
Кристиан
10
@pilau, используя другое замыкание, поможет topicId = 12; function postinsql (topicId) {console.log (topicId); } function setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); TopicID = 13;
Халис Йылбоша
729

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

Пример:

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

Больше деталей:

Фабио Фмс
источник
56
Я не уверен, почему этот ответ не был выбран как лучший. Конечно, работает анонимная функция, но если вы можете просто передать третий параметр в исходный вызов функции setTimeout ... почему бы и нет?
Крис Шоу
54
Потому что это не работает в версиях IE все еще очень в дикой природе.
Аарон
4
Этот ответ фактически позволил мне передать объект события, другие методы - нет. У меня уже была анонимная функция.
Гленн Плас
27
Гораздо лучше ответ. Если у вас есть код, который изменяет ваш параметр между вызовом «setTimeout» и фактическим выполнением анонимной функции - анонимная функция получит измененное значение, а не то, что было во время вызова setTimeout. Например: for (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } это будет записывать «100» 100 раз (проверено на FF). Текущий ответ помогает избежать этого.
root
1
Согласно developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout аргументы обратного вызова для Internet Explorer поддерживаются только в версиях> = 10, будьте осторожны, так как на многих сайтах ie8 и ie9 по-прежнему получают некоторую соответствующую долю.
le0diaz
155

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

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

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

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

Иржи Ветиска
источник
24
С грустью в моем сердце я должен сообщить: это не работает в Internet Explorer. : / Все дополнительные параметры указаны как неопределенные.
Амальговинус
6
Я просто используюvar that = this; setTimeout( function() { that.foo(); }, 1000);
Эд Уильямс
2
Это правильно, и это указано в HTML5. whatwg.org/specs/web-apps/current-work/multipage/…
Гарретт
4
Это точно такой же ответ, как у Фабио .
Дан Даскалеску
1
Согласно developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout аргументы обратного вызова для Internet Explorer поддерживаются только в версиях> = 10, будьте осторожны, так как на многих сайтах ie8 и ie9 по-прежнему получают некоторую соответствующую долю.
le0diaz
45

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

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

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

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

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

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

Способ 1

Используйте forEachи Object.keys, согласно предложению Sukima :

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.

Дэвид Шеррет
источник
2
Примечание: .bindне будет работать для IE8 и ниже [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Я закончил тем, что использовал решение
Schien
1
Если вы находитесь в среде, которая использует, bindто вы также в среде, которая предлагает Object.keysи forEach. Вы можете потерять цикл for и получить «свободную» (как у двух птиц с одним свободным камнем, не свободную от ресурсов) область действия в процессе.
Sukima
@ Дэвид Шеррет, если вы еще не использовали его, обязательно посетите asyncбиблиотеку ( github.com/caolan/async ). Мы широко используем его в Sails и добились отличных результатов за последние 2 года. Он предоставляет методы как параллельно и последовательно для асинхронной forEach, map, reduceи т.д.
mikermcneil
25

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

Использование 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 / связывающийся # With_setTimeout

Дейн
источник
этот контекст может быть передан с первым аргументом bindsetTimeout(postinsql.bind(this, topicId), 4000);
Джузеппе Галано
@GiuseppeGalano полностью, я упомянул это в своем ответе, но это не нужно для этого примера :)
Дейн
Захватывающе, сколько замаскировать частичное использование приложений bind. Это действительно делает для некоторого читаемого кода.
Sukima
bind () поддерживается только из IE9 +, поэтому этот подход не будет работать для <IE9
Санджив,
@Sanjeev Используйте ES5-шим, чтобы он работал в старых
версиях
17

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

Я отвечаю на это снова, 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 может не совпадать. Поэтому важно предварительно связать переменные .

Schien
источник
1
+1 для удобочитаемого решения, немного отличного от моего. Пока у вас есть setTimeout внутри функции settopic, у меня есть функция fDelayed (ваша settopic) внутри функции setTimeout.
Доминик
11

Мой ответ:

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

Объяснение:

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

ИЛИ

Это в основном конвертируется в:

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

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


источник
Это лучший ответ. Многие из этих решений даже не соблюдают тайм-аут. Однако почему вы заключаете первую анонимную функцию в круглые скобки? Я не думаю, что они необходимы для достижения этой цели.
Роберт Хендерсон
это лучший ответ 👍, но пришлось сделать клон, потому что когда значения вроде topicIdизменяются, значение в тайм-ауте также меняется. Клон это исправил
париола
10

замещать

 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()строку и вместо этого передаст функцию.

Русь Кэм
источник
Это не будет работать, потому что результат postinsql (topicId) будет выполнен setTimeout. Вам нужно обернуть его в функцию, как в первом ответе, или использовать помощник, такой как .curry () - setTimeout Prototype (postinsql.curry (topidId), 4000);
shuckster
2
@brownstone: это неправильно. Строка будет оценена, когда истечет время ожидания.
Майлз
9

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

setTimeout (функция, миллисекунды, param1, param2, ...)

например.

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

function alertMsg(message) {
    alert(message)
}
Джатин Верма
источник
1
Может кто-нибудь сказать мне, почему этот ответ не является предпочтительным? это самый простой способ на мой взгляд! Так же просто, какsetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Мажар Зандсалими
1
Да! Это должен быть принятый ответ. От MDN: developer.mozilla.org/en-US/docs/Web/API/...
Хан
5

Я знаю, что прошло 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);
}
Альпеш Патил
источник
4

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

Я думаю, что довольно удобный способ достижения этого - передать 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);
Dominic
источник
4

Ответ Дэвида Мейстера, кажется, заботится о параметрах, которые могут измениться сразу после вызова 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>
Гурджит Сингх
источник
4

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

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

setTimeout(someFunction(params), 1000);

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

setTimeout(() => someFunction(params), 1000); 
Джон Хартман
источник
это очень несовместимо
user151496
Действительно элегантно! Спасибо
Velojet
3

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

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

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

Билли
источник
3

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

Просто так :

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: извините но английский это не мой родной язык!

Anonymous0day
источник
Это слишком сложно по сравнению с другими ответами.
Дан Даскалеску
3

это работает во всех браузерах (IE странный)

setTimeout( (function(x) {
return function() {
        postinsql(x);
    };
})(topicId) , 4000);
user3756459
источник
3

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

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

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

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

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

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

сумасшедший
источник
2

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

function postinsql(topicId)
{
  //alert(topicId);
}
setTimeout(
       postinsql.apply(window,["mytopic"])
,500);
Вишну Прасант Г
источник
1

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)

Garrett
источник
0

@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
}

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

Владислав
источник
0

Поскольку существует проблема с третьим оптональным параметром в 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);
}

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

Вахтанг Тевдорашвили
источник
0

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

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');
Богатые
источник
0

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

var x = 3, y = 4;

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

function delayedSum(param1, param2) {
     alert(param1 + param2); // 7
}
SridharKritha
источник
0

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

setTimeout(postinsql(topicId),4000);
Ганшьям Шарма
источник
-1

Я думаю, что вы хотите:

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

источник
1
Я сталкивался с случаями, когда это просто не работает (всегда приводит к ошибке «функция не определена»), но использование анонимной функции работает. Что разочаровывает, учитывая, что все говорят, что приведенный выше синтаксис должен работать всегда. (может ли быть так, что jQuery каким-то образом помешает методу 'quote as string'?)
DA.
6
Давайте предположим, что topicId - это функция ... или объект. Это не сработает!
Серафеим
Если вы действительно хотите продолжить этот метод, используйте JSON.stringifyдля обычных объектов и массивов, а затем используйте JSON.parseвнутри функции. Однако все поведение будет потеряно, если у объекта есть методы.
ДартКадеус
-2

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

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');
user11385739
источник