设置超时函数回调静态变量

Set Timeout Function CallBack static variables

使用以下代码时:

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

输出是10,我完全明白为什么。

但是,我希望在上面的示例中输出为 5(或者更具体地说是调用设置超时函数时 x 的值,而不是调用回调时的值。)

向我建议的一个选项是调出一个函数并查找数据。

像这样:

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 前端来设置事件的特定 time/length , 以及它的一些其他信息。

我可能同时有 2 个事件,所以当我在那个函数中查找它时,我需要有一种方法来知道使用哪个(假设我有两个 "alarms" ,如果你愿意,设置,一个回调需要知道使用 blah[x] 并且需要知道使用 blah[x+1] 例如)。

我可以查找当前时间并找到已经过去的最近时间,然后标记我是否将其设置为执行任何需要的操作并且 可能 工作,但我想知道如果有一种方法可以包装我用完的变量的当前状态作为(匿名?)函数的一部分。

基本上我正在用 nodejs 编写一个 DVR 应用程序,我正在连接到 Firebase 来管理持久数据,并且在前端 AngularJS,所以我可以保持大部分应用程序断开连接,我正在尝试使用 node-schedule,所以当我在 angular 中添加录制事件时,我可以看到 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....

然后在调用的函数中搜索数组 blah。

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

在运行时或多或少是动态的。有什么办法吗?

(我也不知道这是不是一个好标题,我愿意接受建议)。

只是解决问题的顶部:

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

会显示5.

编辑:Felix Kling 所说的全部内容。请注意,虽然我们在不同的级别创建一个函数,但最终效果是相同的——重要的一点是函数存在,引入一个新的作用域,一个新的变量与原来的 x 断开连接。

EDIT2:伙计们,多给菲利克斯的回答点赞,即使我最初比他快 10 秒,他现在肯定是两个答案中更好的一个,不是公平的,他只有我的赞成票:D

我没有详细阅读所有内容,但我猜您想创建一个新范围来捕获变量的当前值。函数创建作用域,创建和调用函数的一种简单方法是使用 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 和参数设置为您传递给它的特定值。