2015-01-06 2 views
1

При использовании следующий код:Установка таймаута Функция CallBack статические переменные

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

выход 10, и я полностью понимаю, почему.

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

Один из вариантов, который мне предложил, - это вызвать функцию и посмотреть данные.

что-то вроде этого:

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; 

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

Я пишу какое-то программное обеспечение для управления событиями планирования (с использованием node-schedule). Например, я мог бы иметь переднюю часть AngularJS, которая устанавливает конкретное время/длину события и другую информацию об этом.

Возможно, что в это же время у меня было бы 2 события, поэтому, когда я посмотрю на эту функцию, мне нужно будет узнать, какой из них использовать (если у меня есть два «будильника», если вы будет, настройка, один обратный вызов должен знать, чтобы использовать blah [x], и нужно было бы, например, использовать blah [x + 1]).

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

В основном я пишу приложение DVR в nodejs, я подключаюсь к Firebase для управления постоянными данными, а AngularJS - на передней панели, поэтому я могу сохранить большую часть приложения отключенным, я пытаюсь использовать узел-расписание , поэтому, когда я добавляю событие записи в угловое, я вижу изменение данных в firebase, планирую событие, и когда срабатывает обратный вызов, начните запись соответствующего шоу, моя забота заключается в том, что у меня было бы два шоу, которые будут записываться одновременно , и я должен управлять правильно записывать их, и одна возможная идея у меня есть структура данных, таких, как это:

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

Затем поищите через бэ массива в вызываемой функции.

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

Однако это, кажется, что я делаю больше работы, то мне нужно, на мой взгляд, я бы ожидать, чтобы просто нажать эти данные как часть функции, поэтому в основном заменить выше функции с ниже:

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

более или менее динамически во время выполнения. Есть ли способ сделать это?

(Также я понятия не имею, если это хороший заголовок, я открыт для предложений).

+0

Одинаковая базовая идея: http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – epascarello

ответ

3

Я не читал все подробно, но, я думаю, вы хотите создать новую область для захвата текущего значения вашей переменной. Функции создания сферы и простой способ создания и вызова функции будет использовать 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; 

Смотрите также: JavaScript closure inside loops – simple practical example

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

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

.bind создает новую функцию и устанавливает this и параметры к конкретным значениям, которые вы передаете ему.

+0

Я прочитал о привязке немного назад, но, я думаю, я не Понимаете это достаточно, это, похоже, работает на то, что я надеюсь сделать. Также я читал о закрытии в прошлом, но никогда не имел возможности использовать их, поэтому даже не передумал. – onaclov2000

+0

Итак, прочитав вышеприведенный IIFE (который, я думаю, я мог прочитать о начале этого вечера, и я верю), мы вызываем функцию немедленно, и это возвращает функцию со значением (внутри), заданным вызывающей функцией .... – onaclov2000

+0

Да............ –

4

Только обращаясь к верхней части вашего вопроса:

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

покажет 5.

EDIT: Все, что сказал Феликс Клинг. Обратите внимание, что, пока мы создаем функцию на разных уровнях, конечный эффект одинаков - важно то, что существует функция, чтобы ввести новую область с новой переменной, которая отключена от оригинала x.

EDIT2: Ребята, идите upvote ответ Феликса немного больше, даже если я побью его первоначально на 10 секунд, его это уже, безусловно, лучшее из двух ответов, не справедливо, он имеет только мой upvote: D

Смежные вопросы