我正在尝试使用更改配置数据作为输入来安排一系列任务按时间间隔运行:
let configData = initConfig(); // Initialize configuration data from file
setInterval(taskA.bind(null, configData), TASK_A_WAIT); // Task using config data
setInterval(taskB.bind(null, configData), TASK_B_WAIT); // Task using config data
setInterval(taskC.bind(null, configData), TASK_C_WAIT); // Task using config data
setInterval(refreshConfig.bind(null, (error, result) => { // Update config data
if (error) handleError(error);
else configData = result;
}), CONFIG_REFRESH_WAIT);
目标是使用最后一个setInterval()
按时间间隔更新配置数据,以便前三个setInterval()
始终拥有最新的数据。但它会起作用吗?
在javascript的语义中,上面实际上是否会在每个时间间隔内将函数重新绑定到最新的configData
对象?在这种情况下何时会发生绑定?
答案 0 :(得分:3)
由于bind()
未包含在另一个函数中,因此它会就地同步执行。
任务函数绑定到原始configData
。如果它与configData = result
重新分配,则不会影响绑定函数。
任务函数应该包含函数以重新分配configData
:
setInterval(() => { taskA(configData) }, TASK_A_WAIT)
与bind
一起使用的另一个选项是保留configData
对象的相同引用,这仅在初始configData
是对象时才有效:
setInterval(refreshConfig.bind(null, (error, result) => {
...
Object.assign(configData, result);
}), CONFIG_REFRESH_WAIT);
如果configData
已经有可能无法覆盖的属性,则应首先cleared。
答案 1 :(得分:2)
如果您希望任务继续引用configData
的实时版本,您应该将匿名包装函数传递给setInterval()
的每个调用,这样就可以将符号变量引用作为范围将原始对象引用绑定到每个函数:
let configData = initConfig(); // Initialize configuration data from file
setInterval(() => taskA(configData), TASK_A_WAIT); // Task using config data
setInterval(() => taskB(configData), TASK_B_WAIT); // Task using config data
setInterval(() => taskC(configData), TASK_C_WAIT); // Task using config data
setInterval(refreshConfig.bind(null, (error, result) => { // Update config data
if (error) handleError(error);
else configData = result;
}), CONFIG_REFRESH_WAIT);
或者,如果您不希望更改引用,并且您知道配置的结构永远不会更改,您可能更愿意将configData
作为const
引用并使用{{1} }使用Object.assign()
中的新值覆盖result
个密钥的浅层副本,覆盖configData
中的每个密钥:
result