0

我正在使用 node.js 开发一个项目。我正在提取大量 JSON 数据,我需要安排作业以根据接收到的数据将数据写入串行端口。我正在为此任务使用节点计划。有几个作业需要安排,每个作业的命令都不同。我发现在调用scheduleJob中传递给函数的参数是在执行时解释的,而不是在 for 循环中安排的时候。关于如何使字符串参数保持不变的任何想法?

代码示例:

var schedule = require('node-schedule');
var schedules[];
…

var startrule = new schedule.RecurrenceRule();
var start_hour = thejson.start_hour;
var start_minute = thejson.start_minute;
for (var k = 0; k < thejson.zones.length; k++)
{
  //start
  startrule.hour = start_hour;
  startrule.minute = start_minute;
  var start = schedule.scheduleJob(startrule, function(){
    writeSerial('//S' + thejson.zones[k].number + ',1');
  });
  schedules.push(start);  //upon next json update, old schedules in array are cancelled.
}

当它执行时,由于未知thejson.zones[k].number而失败。k如何使该字符串参数writeSerial()成为静态/常量?我已经尝试将它粘贴在一个数组中并将一个索引传递给writeSerial计划内,但该索引变量也在计划执行时被解释。

4

2 回答 2

2

您必须将计划作业的建立包装在一个函数中,以提供每个作业唯一的词法范围:

  var start = schedule.scheduleJob(startrule, function(number){
    return function() {
        writeSerial('//S' + number + ',1');
    };
  }(thejson.zones[k].number));

该匿名和立即调用函数的参数“数字”确保它返回的预定函数将使用数据结构该部分的安全副本。

如果没有那个额外的层,您安排的每个作业都共享相同的变量“k”。当“k”等于列表的长度时,使用“k”的循环结束,因此每个作业(当它最终按计划调用时)看到“k”指向数组末尾之外的一个点.

于 2013-10-02T17:20:57.227 回答
1

我首选的解决方案是创建一个偏函数:

var start = schedule.scheduleJob(startrule, function(number) {
  writeSerial('//S' + number + ',1');
}.bind(null, thejson.zones[k].number);

这将创建一个匿名函数,该函数的第一个参数已经绑定到它。

于 2013-10-02T17:48:57.880 回答