Establecer las funciones de tiempo de espera CallBack estáticas

Al usar el siguiente código:

var x = 5; setTimeout(function() { console.log(x); }, 2500); x = 10; 

La salida es 10, y entiendo totalmente por qué.

Sin embargo, me gustaría que la salida fuera 5 en el ejemplo anterior (o más específicamente el valor de x cuando se llama a la función de tiempo de espera establecido, no el valor en el momento en que se llama a la callback).

Una opción que se me ha sugerido es llamar a una función y buscar los datos.

algo como esto:

 var x = 5; var value_of_x_at_some_time = function() { return old_value_of_x; } setTimeout(function() { console.log(value_of_x_at_some_time()); }, 2500); old_value_of_x = x; x = 10; 

Entiendo la idea, sin embargo, esto significaría que tendría que pasar por una matriz y calcular cuál es el valor correcto. Este puede ser el camino correcto, pero no me parece correcto.

Estoy escribiendo algún software para administrar eventos de progtwigción, (usando la progtwigción de nodos). Por ejemplo, podría tener un extremo delantero de AngularJS que establezca un tiempo / duración particular de un evento, y alguna otra información del mismo.

Es posible que pueda tener 2 eventos al mismo tiempo, así que cuando busque en esa función necesitaría tener una forma de saber cuál usar (asumiendo que tengo dos “alarmas”, si lo desea, configuración, una llamada de retorno necesitaría saber usar blah [x] y uno necesitaría saber usar blah [x + 1] por ejemplo).

Podría buscar la hora actual y encontrar la hora más cercana que ya haya pasado y luego marcar si la configuro para hacer lo que fuera necesario y podría funcionar, pero me preguntaba si habría una manera de ajustar el estado actual de las variables que utilizo arriba como parte de la función (¿anónimo?).

Básicamente estoy escribiendo una aplicación DVR en nodejs, me estoy conectando a Firebase para administrar datos persistentes, y AngularJS en el extremo delantero, así puedo mantener la mayoría de la aplicación desconectada, estoy tratando de usar la progtwigción de nodos, por lo que cuando agregar un evento de grabación en angular, puedo ver el cambio de datos en base de fuego, progtwigr el evento, y cuando se dispara la callback comenzar a grabar el progtwig apropiado, mi preocupación es que podría tener dos progtwigs configurados para grabar al mismo tiempo, y tengo para gestionar la grabación correctamente, y una idea posible que tengo es una estructura de datos como esta:

 var recording_event = { time: "1500", date: "01012015", length: "3600", //time in ms channel: "51", program: "1", scheduled: "true", recording: "false" } var blah[] = recording_events.... 

Luego busque a través de la matriz blah en la función llamada.

 var lookup_value() { // loop through blah[] till you find the event closest to current time, // check if recording is true, if not // set the value of recording to true // else search for the next matching event // assume x is the index that matches correctly // finally return the event return blah[x]; } setTimeout(function() { var temp = lookup_value(); // set tuner to temp.channel // set tuner to temp.program // start recording for length of time temp.length }, 2500); 

Sin embargo, esto parece que estoy haciendo más trabajo del que necesito, en mi mente esperaría simplemente enviar estos datos como parte de la función, así que básicamente reemplace la función anterior con la siguiente:

 temp = x //"newly secheduled event" setTimeout(function() { // set tuner to temp.channel (value at the time of the scheduling) // set tuner to temp.program (value at the time of the scheduling) // start recording for length of time temp.length (value at the time of the scheduling) }, 2500); 

Más o menos dinámicamente en tiempo de ejecución. Hay alguna manera de hacer esto?

(Tampoco tengo idea de si este es un buen título, estoy abierto a sugerencias).

No leí todo en detalle, pero creo que desea crear un nuevo ámbito para capturar el valor actual de su variable. Las funciones crean un scope y una forma fácil de crear y llamar a una función es usar un IIFE :

 var x = 5; setTimeout((function(y) { // this function is executed immediately and passed the current value of `x` return function () { // this is function that is passed to setTimeout // since every function is a closure, it has access to the IIFE parameter y console.log(y); }; }(x)), 2500); x = 10; 

Ver también: cierre de JavaScript dentro de bucles – ejemplo práctico simple

Sin embargo, hay una opción aún más simple: puede vincular un valor específico a un parámetro de una función usando .bind :

 setTimeout(function(y) { console.log(y); }.bind(null, x), 2500); 

.bind crea una nueva función y establece this y los parámetros a los valores específicos que le pasas.

Solo abordando la parte superior de tu pregunta:

 var x = 5; (function(currentX) { setTimeout(function () { console.log(currentX); }, 2500); })(x); x = 10; 

mostrará 5 .

EDIT : Todo lo que dijo Félix Kling. Tenga en cuenta que si bien creamos una función en diferentes niveles, el efecto final es el mismo: lo importante es que existe una función para introducir un nuevo ámbito, con una nueva variable que está desconectada de la x original.

EDIT2 : Chicos, suban más la respuesta de Félix un poco más, incluso si le gané originalmente por 10 segundos, esta es por ahora la mejor de las dos respuestas, no es justo, solo tiene mi voto: D