¿Cómo puedo pasar un parámetro a una devolución de llamada setTimeout ()?

827

Tengo un código JavaScript que se parece a:

function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    var topicId = xmlhttp.responseText;
    setTimeout("postinsql(topicId)",4000);
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}

Recibo un error que topicIdno está definido. Todo funcionaba antes de usar la setTimeout()función.

Quiero postinsql(topicId)que se llame mi función después de un tiempo. ¿Qué tengo que hacer?

Zeeshan Rang
fuente
75
Me duele un poco comentar sobre un tema tan antiguo, pero solo tengo que ofrecer una tercera versión (que en mi opinión es mucho más limpia): setTimeout (postinsql.bind (null, topicId), 4000)
Hobblin
14
@Hobblin: ¿por qué dolería dejar las cosas claras? ¿No le dolería más a otros aterrizar en esta pregunta popular y ver el estilo de llamada antiguo y desalentado?
Dan Dascalescu
2
todo está claro aquí: w3schools.com/jsref/met_win_settimeout.asp
Vladislav
@dbliss Mi sugerencia ya se mencionó en varias de las respuestas y se agregó como respuesta aquí: stackoverflow.com/a/15620038/287130 Pero me alegro de que mi sugerencia sea apreciada;)
Hobblin
@ Hobblin ah, muchas gracias por señalar eso. Me había desplazado buscando una respuesta publicada por ti y me la perdí.
dbliss

Respuestas:

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

Debe alimentar una función anónima como parámetro en lugar de una cadena, el último método ni siquiera debería funcionar según la especificación ECMAScript, pero los navegadores son indulgentes. Esta es la solución adecuada, nunca confíes en pasar una cadena como una 'función' al usar setTimeout()o setInterval(), es más lenta porque tiene que ser evaluada y simplemente no está bien.

ACTUALIZAR:

Como dijo Hobblin en sus comentarios a la pregunta, ahora puede pasar argumentos a la función dentro de setTimeout usando Function.prototype.bind().

Ejemplo:

setTimeout(postinsql.bind(null, topicId), 4000);
meder omuraliev
fuente
30
window.setTimeoutes un método DOM y, como tal, no está definido por la especificación ECMAScript. Pasar una cadena siempre ha funcionado en los navegadores, y es un estándar de facto ; de hecho, la capacidad de pasar un objeto de función se agregó más tarde, con JavaScript 1.2, forma parte explícita de la especificación de borrador HTML5 ( whatwg.org/specs/web -apps / current-work / multipage / ... ). Sin embargo, el uso de una cadena en lugar de un objeto de función generalmente se considera mal estilo porque es esencialmente una forma de retraso eval().
Miles
2
var temp = setTimeout (function () {postinsql (topicId);}, 4000); clearTimeout (temp); ??
Josh Mc
12
¿Qué pasaría si topicId se cambia después de que se estableció el tiempo de espera, pero antes de que se llame a la función?
pilau
22
@pilau ese es exactamente mi problema: si las variables utilizadas en la función anónima cambian antes del tiempo de espera (como en un bucle for), entonces también cambiará dentro de la función. Entonces, en mi ejemplo, configurar 5 tiempos de espera diferentes en un ciclo for realmente terminó usando las mismas variables. ¡Tenga cuidado al usar esta respuesta!
Cristian
10
@pilau usando otro cierre ayudará a topicId = 12; función postinsql (topicId) {console.log (topicId); } función setTimeOutWithClosure (topicId) {setTimeout (function () {postinsql (topicId);}, 1000)} setTimeOutFunction (topicId); topicId = 13;
Halis Yılboğa
728

En los navegadores modernos, el "setTimeout" recibe un tercer parámetro que se envía como parámetro a la función interna al final del temporizador.

Ejemplo:

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

Más detalles:

Fabio Phms
fuente
56
No estoy seguro de por qué esta respuesta no fue seleccionada como la mejor. El uso de una función anónima funciona, claro, pero si simplemente puede pasar un tercer parámetro a la llamada a la función setTimeout original ... ¿por qué no?
Kris Schouw
54
Debido a que no funciona en versiones de IE todavía mucho en la naturaleza.
Aaron
44
Esta respuesta realmente me permitió pasar un objeto de evento, los otros métodos no. Ya tenía una función anónima.
Glenn Plas
27
Por mucho mejor respuesta. Si tiene un código que modifica su parámetro entre la llamada "setTimeout" y la ejecución real de la función anónima, la función anónima recibirá un valor modificado, no lo que era en el momento de la llamada setTimeout. por ejemplo: for (var i = 0; i <100; i ++) {setTimeout (function () {console.write (i);}, 0); } esto registrará "100" a 100 veces (probado en FF). La respuesta actual ayuda a evitar esto.
raíz
1
Según developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout, los argumentos de devolución de llamada para Internet Explorer solo son compatibles con las versiones> = 10, tenga cuidado, ya que en muchos sitios ie8 e ie9 todavía obtiene algo relevante.
le0diaz
155

Después de investigar y probar, la única implementación correcta es:

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

setTimeout pasará todos los parámetros adicionales a su función para que puedan procesarse allí.

La función anónima puede funcionar para cosas muy básicas, pero dentro de un objeto en el que debe usar "esto", no hay forma de hacerlo funcionar. Cualquier función anónima cambiará "esto" para que apunte a la ventana, por lo que perderá su referencia de objeto.

Jiri Vetyska
fuente
24
Es con tristeza en mi corazón que debo informar: esto no funciona en Internet Explorer. : / Todos los parámetros adicionales aparecen como indefinidos.
Amalgovinus
66
Solo usovar that = this; setTimeout( function() { that.foo(); }, 1000);
Ed Williams
2
Esto es correcto y se especifica en HTML5. whatwg.org/specs/web-apps/current-work/multipage/…
Garrett
44
Esta es exactamente la misma respuesta que la de Fabio .
Dan Dascalescu
1
Según developer.mozilla.org/es/docs/Web/API/WindowTimers/setTimeout, los argumentos de devolución de llamada para Internet Explorer solo son compatibles con las versiones> = 10, tenga cuidado, ya que en muchos sitios ie8 e ie9 todavía obtiene algo relevante.
le0diaz
45

Esta es una pregunta muy antigua con una respuesta ya "correcta", pero pensé en mencionar otro enfoque que nadie ha mencionado aquí. Esto se copia y pega de la excelente biblioteca de subrayado :

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

Puede pasar tantos argumentos como desee a la función llamada por setTimeout y como un bono adicional (bueno, generalmente un bono) el valor de los argumentos pasados ​​a su función se congela cuando llama a setTimeout, por lo que si cambian de valor en algún momento entre cuando se llama a setTimeout () y cuando se agota el tiempo de espera, bueno ... eso ya no es tan horriblemente frustrante :)

Aquí hay un violín donde puedes ver lo que quiero decir.

David Meister
fuente
77
Esa respuesta realmente funciona, pero parece que tienes una biblioteca que yo no tengo. Aquí está la pequeña solución para que funcione: en lugar de slice.call, use Array.prototype.slice.call (argumentos, 2)
Melanie
77
@Melanie "alguna biblioteca"? Dije en la respuesta que es la biblioteca de subrayado : underscorejs.org . Pero sí, Array.prototype.slice tiene un alias para cortar dentro de esa biblioteca, por lo que debe hacerlo usted mismo si no lo está usando, buen lugar :)
David Meister
38

Recientemente me encontré con la situación única de la necesidad de usar un setTimeouten un bucle . Comprender esto puede ayudarlo a comprender cómo pasar parámetros a setTimeout.

Método 1

Uso forEachy Object.keys, según la sugerencia de Sukima :

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

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

Recomiendo este método

Método 2

Uso 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/

Método 3

O si no puede usar forEacho bind, use un IIFE :

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

Método 4

Pero si no te importa IE <10, entonces podrías usar la sugerencia de Fabio :

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

Método 5 (ES6)

Use una variable de ámbito de bloque:

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

Aunque todavía recomendaría usar Object.keyscon forEachES6.

David Sherret
fuente
2
Nota: .bindno funcionará para IE8 y versiones inferiores [ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ]. Terminé usando la solución de Schien: stackoverflow.com/a/21213723/1876899
cjspurgeon
1
Si estás en un entorno que usa bind, también estás en un entorno que ofrece Object.keysy forEach. Puede perder el bucle for y obtener un alcance de función "libre" (como en dos pájaros con una piedra libre y sin recursos) en el proceso.
Sukima
@David Sherret en caso de que no lo haya usado antes, definitivamente revise la asyncbiblioteca ( github.com/caolan/async ). Lo usamos ampliamente en Sails y hemos tenido excelentes resultados durante los últimos 2 años. Se proporciona métodos tanto en paralelo y en serie para asíncrono forEach, map, reduce, etc.
mikermcneil
25

Hobblin ya comentó esto sobre la pregunta, ¡pero debería ser una respuesta realmente!

Usar Function.prototype.bind()es la forma más limpia y flexible de hacerlo (con la ventaja adicional de poder establecer el thiscontexto):

setTimeout(postinsql.bind(null, topicId), 4000);

Para obtener más información, consulte estos enlaces de 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

dain
fuente
Este contexto se puede pasar con el primer argumento de enlacesetTimeout(postinsql.bind(this, topicId), 4000);
Giuseppe Galano
@GiuseppeGalano totalmente, mencioné eso en mi respuesta, pero no es necesario para este ejemplo :)
desde el
Fascinante cuántos brillo sobre aplicaciones parciales usando bind. Realmente crea un código legible.
Sukima
bind () solo es compatible con IE9 +, por lo que este enfoque no funcionará para <IE9
Sanjeev
@Sanjeev Use ES5 shim para que funcione en IE más antiguo: github.com/es-shims/es5-shim
gregers
17

Algunas respuestas son correctas pero complicadas.

Estoy respondiendo esto nuevamente, 4 años después, porque todavía me encuentro con un código demasiado complejo para resolver exactamente esta pregunta. Hay una solución elegante.

En primer lugar, no pase una cadena como primer parámetro cuando llame a setTimeout porque invoca efectivamente una llamada a la función lenta "eval".

Entonces, ¿cómo pasamos un parámetro a una función de tiempo de espera? Mediante el uso de cierre:

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

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

Algunos han sugerido usar la función anónima al llamar a la función de tiempo de espera:

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

La sintaxis funciona. Pero cuando se llama al settopic de tiempo, es decir, 4 segundos después, el objeto XHR puede no ser el mismo. Por lo tanto, es importante vincular previamente las variables .

Schien
fuente
1
+1 para una solución legible, ligeramente diferente a la mía. Si bien tiene setTimeout dentro de la función settopic, tengo la función fDelayed (su settopic) dentro de la función setTimeout.
Dominic
11

Mi respuesta:

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

Explicación:

La función anónima creada devuelve otra función anónima. Esta función tiene acceso a la aprobada originalmente topicId, por lo que no cometerá un error. La primera función anónima se llama inmediatamente, pasando topicId, por lo que la función registrada con un retraso tiene acceso topicIden el momento de la llamada, a través de cierres.

O

Esto básicamente se convierte en:

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

EDITAR: Vi la misma respuesta, así que mira la suya. ¡Pero no robé su respuesta! Solo olvidé mirar. Lea la explicación y vea si ayuda a entender el código.


fuente
Esta es la mejor respuesta. Muchas de estas soluciones ni siquiera cumplirán con el tiempo de espera. Sin embargo, ¿por qué estás envolviendo la primera función anónima entre paréntesis? No creo que sean necesarios para lograr esto.
Robert Henderson
esta es la mejor respuesta 👍, pero tuvo que hacer un clon porque cuando los valores como topicIdse altera el valor en el tiempo de espera también cambia. Un clon lo arregló
pariola
10

Reemplazar

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

con

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

o mejor aún, reemplace la expresión de cadena con una función anónima

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

EDITAR:

El comentario de Brownstone es incorrecto, esto funcionará según lo previsto, como se demuestra al ejecutar esto en la consola Firebug

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

Tenga en cuenta que estoy de acuerdo con otros a los que debe evitar pasar una cadena, setTimeoutya que esto invocará eval()la cadena y en su lugar pasará una función.

Russ Cam
fuente
Esto no funcionará porque setTimeout ejecutará el resultado de postinsql (topicId). Debe envolverlo en una función como con la primera respuesta, o usar un ayudante como Prototype's .curry () - setTimeout (postinsql.curry (topidId), 4000);
shuckster
2
@brownstone: Eso es incorrecto. La cadena se evaluará cuando se active el tiempo de espera.
Millas
9

Puede pasar el parámetro a la función de devolución de llamada setTimeout como:

setTimeout (función, milisegundos, param1, param2, ...)

p.ej.

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

function alertMsg(message) {
    alert(message)
}
Jatin Verma
fuente
1
¿Alguien puede decirme por qué esta respuesta no es la preferida? ¡Esta es la forma más simple en mi opinión! Tan simple comosetTimeout( (p) => { console.log(p); }, 1000, "hi" );
Mazhar Zandsalimi
1
¡Si! Esta debería ser la respuesta aceptada. De MDN: developer.mozilla.org/en-US/docs/Web/API/…
Han
5

Sé que han pasado 10 años desde que se hizo esta pregunta, pero aún así, si te has desplazado hasta aquí, supongo que todavía tienes algún problema. La solución de Meder Omuraliev es la más simple y puede ayudarnos a la mayoría de nosotros, pero para aquellos que no quieren tener ningún enlace, aquí está:

  1. Use Param para setTimeout
setTimeout(function(p){
//p == param1
},3000,param1);
  1. Usar expresión de función invocada inmediatamente (IIFE)
let param1 = 'demon';
setTimeout(function(p){
    // p == 'demon'
},2000,(function(){
    return param1;
})()
);
  1. Solución a la pregunta
function statechangedPostQuestion()
{
  //alert("statechangedPostQuestion");
  if (xmlhttp.readyState==4)
  {
    setTimeout(postinsql,4000,(function(){
        return xmlhttp.responseText;
    })());
  }
}

function postinsql(topicId)
{
  //alert(topicId);
}
Alpesh Patil
fuente
4

Sé que es viejo pero quería agregar mi sabor (preferido) a esto.

Creo que una forma bastante legible de lograr esto es pasarle topicIda una función, que a su vez usa el argumento para hacer referencia internamente al ID del tema. Este valor no cambiará incluso si topicIden el exterior se cambiará poco después.

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

o corto:

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

La respuesta de David Meister parece ocuparse de los parámetros que pueden cambiar inmediatamente después de la llamada a setTimeout () pero antes de que se llame a la función anónima. Pero es demasiado engorroso y no muy obvio. Descubrí una forma elegante de hacer más o menos lo mismo usando IIFE (expresión de función invitada inmediatamente).

En el siguiente ejemplo, la currentListvariable se pasa al IIFE, que la guarda en su cierre, hasta que se invoca la función retrasada. Incluso si la variable currentListcambia inmediatamente después del código que se muestra, setInterval()hará lo correcto.

Sin esta técnica IIFE, setTimeout()definitivamente se llamará a la función para cada h2elemento en el DOM, pero todas esas llamadas verán solo el valor de texto del último h2 elemento.

<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>
Gurjeet Singh
fuente
4

En general, si necesita pasar una función como devolución de llamada con parámetros específicos, puede usar funciones de orden superior. Esto es bastante elegante con ES6:

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

setTimeout(someFunction(params), 1000);

O si someFunctiones de primer orden:

setTimeout(() => someFunction(params), 1000); 
John Hartman
fuente
esto es muy incompatible
user151496
Elegante por cierto! Gracias
Velojet
3

Tenga en cuenta que la razón por la que no se definió topicId según el mensaje de error es que existía como una variable local cuando se ejecutó setTimeout, pero no cuando ocurrió la llamada retrasada a postinsql. La vida útil variable es especialmente importante a la que se debe prestar atención, especialmente cuando se intenta algo como pasar "esto" como referencia de objeto.

Escuché que puede pasar topicId como tercer parámetro a la función setTimeout. No se dan muchos detalles, pero obtuve suficiente información para que funcione, y tiene éxito en Safari. Sin embargo, no sé qué significan sobre el "error de milisegundos". Compruébalo aquí:

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

porra
fuente
3

¿Cómo resolví esta etapa?

solo así:

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

¡setTimeout espera una referencia a una función, así que la creé en un cierre, que interpreta mis datos y devuelve una función con una buena instancia de mis datos!

Quizás puedas mejorar esta parte:

_deepFunction(_deepData);

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

Lo probé en Chrome, Firefox e IE y se ejecuta bien, no sé sobre rendimiento, pero necesitaba que funcionara.

una prueba de muestra:

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

Tal vez pueda cambiar la firma para que sea más adecuada:

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

Y finalmente para responder la pregunta original:

 myNass_setTimeOut( postinsql, 4000, topicId );

Espero que pueda ayudar!

PD: lo siento, pero el inglés no es mi lengua materna.

Anónimo0day
fuente
Esto es demasiado complicado, en comparación con otras respuestas.
Dan Dascalescu
3

esto funciona en todos los navegadores (IE es un bicho raro)

setTimeout( (function(x) {
return function() {
        postinsql(x);
    };
})(topicId) , 4000);
usuario3756459
fuente
3

si quieres pasar variable como param intentemos esto

si el requisito es function y var como parmas, intente esto

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

si el requisito es solo variable como un parámetro, intente esto

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

Puedes probar esto con ES5 y ES6

hombre loco
fuente
2

Puede probar la funcionalidad predeterminada de 'apply ()' algo como esto, puede pasar más cantidad de argumentos como su requisito en la matriz

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

setTimeout es parte del DOM definido por WHAT WG.

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

El método que desea es: -

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

Programa un tiempo de espera para ejecutar el controlador después del tiempo de espera milisegundos. Cualquier argumento se pasa directamente al controlador.

setTimeout(postinsql, 4000, topicId);

Aparentemente, los argumentos adicionales son compatibles con IE10. Alternativamente, puede usar setTimeout(postinsql.bind(null, topicId), 4000);, sin embargo, pasar argumentos adicionales es más simple, y eso es preferible.

Factoid histórico: en días de VBScript, en JScript, el tercer parámetro de setTimeout era el lenguaje, como una cadena, por defecto a "JScript" pero con la opción de usar "VBScript". https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/aa741500(v%3Dvs.85)

Garrett
fuente
0

@Jiri Vetyska gracias por la publicación, pero hay algo mal en tu ejemplo. Necesitaba pasar el objetivo que está suspendido (esto) a una función de tiempo de espera agotado y probé su enfoque. Probado en IE9: no funciona. También investigué un poco y parece que, como se señaló aquí, el tercer parámetro es el lenguaje de script que se está utilizando. No se mencionan parámetros adicionales.

Entonces, seguí la respuesta de @ meder y resolví mi problema con este código:

$('.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
}

Espero que esto sea útil para alguien más.

Vladislav
fuente
0

Como hay un problema con el tercer parámetro optonal en IE y el uso de cierres nos impide cambiar las variables (en un bucle, por ejemplo) y aún lograr el resultado deseado, sugiero la siguiente solución.

Podemos intentar usar la recursividad de esta manera:

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);
}

Necesitamos asegurarnos de que nada más cambie estas variables y que escribamos una condición de recursión adecuada para evitar una recursión infinita.

Vakhtang Tevdorashvili
fuente
0

// Estas son tres respuestas muy simples y concisas:

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');
Rico
fuente
0

Responde la pregunta pero con una simple función de suma con 2 argumentos.

var x = 3, y = 4;

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

function delayedSum(param1, param2) {
     alert(param1 + param2); // 7
}
SridharKritha
fuente
0

Debe eliminar las comillas de su setTimeOutllamada de función de esta manera:

setTimeout(postinsql(topicId),4000);
Ghanshyam Sharma
fuente
-1

Creo que quieres:

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

fuente
1
Me he encontrado con instancias en las que eso simplemente no funciona (siempre resulta en un error de 'función no definida') pero el uso de la función anónima sí funciona. Lo cual es frustrante dado que todos parecen decir que la sintaxis anterior siempre debería funcionar. (¿podría ser que jQuery de alguna manera se interponga en el método de 'cita como cadena'?)
DA.
66
Supongamos que topicId es una función ... o un objeto. ¡Esto no funcionará!
Serafeim
Si realmente desea continuar con este método, úselo JSON.stringifypara objetos y matrices normales, y luego úselo JSON.parsedentro de la función. Sin embargo, todo comportamiento se perderá si el objeto tiene métodos.
DarthCadeus
-2

// Estas son tres respuestas muy simples y concisas:

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');
usuario11385739
fuente