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

Resuelto Zeeshan Rang asked hace 15 años • 30 respuestas

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 elsetTimeout() función.

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

Zeeshan Rang avatar Jul 28 '09 04:07 Zeeshan Rang
Aceptado
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 simplemente indulgentes. Ésta es la solución adecuada. Nunca confíes en pasar una cadena como una 'función' cuando uses setTimeout()o setInterval(). Es más lento, porque hay que evaluarlo y simplemente no está bien.

ACTUALIZAR:

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

Ejemplo:

setTimeout(postinsql.bind(null, topicId), 4000);
meder omuraliev avatar Jul 27 '2009 21:07 meder omuraliev

En los navegadores modernos (es decir, IE11 y posteriores), "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);
Expandir fragmento

Más detalles en función global setTimeout() - MDN

Fabio Phms avatar Sep 21 '2011 17:09 Fabio Phms

Después de investigar y probar un poco, 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 en el caso de un objeto donde tienes que usar "esto", no hay forma de hacer que funcione. Cualquier función anónima cambiará "esto" para que apunte a la ventana, por lo que perderá la referencia del objeto.

Jiri Vetyska avatar Oct 30 '2012 22:10 Jiri Vetyska

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 guiones bajos :

_.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 beneficio adicional (bueno, generalmente un beneficio), 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 el momento en que se llama a setTimeout() y el momento en que se agota el tiempo de espera, bueno... eso ya no es tan espantosamente frustrante :)

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

David Meister avatar Dec 18 '2012 14:12 David Meister