w3schools usar como javascript parameters callback settimeout

javascript - usar - settimeout typescript



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

¿Cómo resolví esta etapa?

solo asi

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 el 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 usted puede cambiar la firma para que sea más conveniente:

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 responder a la pregunta original:

myNass_setTimeOut( postinsql, 4000, topicId );

Espero que pueda ayudar!

ps: lo siento pero el inglés no es mi lengua materna!

Tengo un código de 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 el error de que topicId no está definido. Todo funcionaba antes de usar la función setTimeout() .

Quiero que mi función postinsql(topicId) sea ​​llamada después de algún tiempo. ¿Qué tengo que hacer?


@Jiri Vetyska, gracias por la publicación, pero hay un error en tu ejemplo. Necesitaba pasar el objetivo que está fuera (esto) a una función de tiempo de espera y probé tu enfoque. Probado en IE9 - no funciona. También hice algunas investigaciones y parece que, como se señaló w3schools.com/jsref/met_win_settimeout.asp el tercer parámetro es el lenguaje de script que se está utilizando. No hay mención sobre parámetros adicionales.

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

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

Esperanza, esto es útil para otra persona.


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 al llamar a setTimeout porque invoca efectivamente una llamada a la lenta función "eval".

Entonces, ¿cómo pasamos un parámetro a una función de tiempo de espera? Utilizando 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 para cuando se llama a settopic, es decir, 4 segundos después, el objeto XHR puede no ser el mismo. Por lo tanto, es importante pre-enlazar las variables .


Como hay un problema con el tercer parámetro opcional 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 tratar de usar la recursión de esta manera:

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

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


Creo que quieres:

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


Después de hacer algunas investigaciones y pruebas, 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 la instancia de un objeto en el que tiene que usar "esto", no hay forma de hacerlo funcionar. Cualquier función anónima cambiará "esto" para apuntar a la ventana, por lo que perderá su referencia de objeto.


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 someFunction es de primer orden:

setTimeout(() => someFunction(params), 1000);



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

_.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 una bonificación) el valor de los argumentos pasados ​​a su función se congelan 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, bueno ... eso ya no es tan terriblemente frustrante :)

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


Hace poco me encontré con la situación única de tener que usar un setTimeout en un bucle . Comprender esto puede ayudarlo a entender cómo pasar parámetros a setTimeout .

Método 1

Utilice forEach y Object.keys , según la suggestion 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

Use 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 forEach o 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 puedes usar la suggestion de Fabio:

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

Método 5 (ES6)

Utilice 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.keys with forEach en ES6.


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

Usar Function.prototype.bind() es la forma más limpia y flexible de hacer esto (con la ventaja adicional de poder establecer this contexto):

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

Para más información vea 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


La respuesta de David Meister parece tener cuidado con 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 prácticamente lo mismo usando IIFE (expresión de función inmediatamente incorporada).

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

Sin esta técnica IIFE, la función setTimeout() definitivamente será llamada para cada elemento h2 en el DOM, pero todas esas llamadas verán solo el valor de texto del último elemento 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>



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 al topicId pasado originalmente, por lo que no cometerá un error. La primera función anónima se llama inmediatamente, pasando a topicId , por lo que la función registrada con un retraso tiene acceso a topicId en el momento de la llamada, a través de los cierres.

O

Esto básicamente se convierte en:

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

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


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

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


Reemplazar

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

con

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

o mejor aún, reemplaza 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 demostró 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 los demás en que debe evitar pasar una cadena a setTimeout ya que esto llamará eval() en la cadena y, en cambio, aprobará una función.


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

Creo que una forma bastante legible de lograr esto es pasar el topicId a una función, que a su vez usa el argumento para hacer referencia a la ID del tema internamente. Este valor no cambiará incluso si topicId en el exterior se modificará 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);


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

He oído 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 funcionara, y es exitoso en Safari. Sin embargo, no sé qué quieren decir con el "error de milisegundos". Échale un vistazo aquí:

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


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

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


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

Debe alimentar una función anónima como un parámetro en lugar de una cadena, el último método no debería funcionar según la especificación ECMAScript, pero los navegadores son simplemente indulgentes. Esta es la solución adecuada, nunca confíe en pasar una cadena como una ''función'' cuando use setTimeout() o setInterval() , es más lento porque tiene que ser evaluado y simplemente no es correcto.

ACTUALIZAR:

Como Hobblin dijo 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);