闭包&asynchronousnode.jsfunction

所有,

尝试让我的头在一个node.js上下文(asynchronous调用)closures。

我有以下代码:

timer = setInterval(pollOID, 1000); function pollOID() { for (channel in channels) { session.get({ oid: channels[channel].oid }, function (varbinds) { console.log("The " + channels[channel].name + " is " + varbinds); }); } } 

该代码每秒轮询一次路由器的SNMP数据,使用setIntervalcallback中的循环来查询路由器的几个SNMP实体。 session.get函数有一个asynchronouscallback来处理来自路由器的结果。

SNMP位工作正常,我的问题是关于如何在会话asynchronouscallback内持续循环variables通道的值。

我得到以下结果:

 The Download Attenuation is 7.5 The Download Attenuation is 361600 The Download Attenuation is 60 

因此,循环variables通道正在改变每个调用session.get,因为函数从路由器返回正确的值。 我的问题是channels [channel] .name使用通道的当前值,在callback返回时,通道已经结束,通道是2(第三个循环,即名称string“download attenuation”)。 所以我需要在session.getcallback函数中保留通道的值,当callback函数被调用的时候,这个值会在session.getcallback中使用正确的通道[channel] .name。

我知道我必须使用闭包,但尝试了一些不同的方法后,我无法正常工作。 任何线索指向我在正确的方向吗? 谢谢!

您可以创build一个简单的闭包来保存channel的本地副本。

  function pollOID() { for (channel in channels) { (function(channel){ session.get({ oid: channels[channel].oid }, function (varbinds) { console.log("The " + channels[channel].name + " is " + varbinds); }); })(channel); } 

或者你也可以使用bind来传入参数,但是上下文会在callback中改变。

 for (channel in channels) { session.get({ oid: channels[channel].oid }, (function (channel, varbinds) { console.log("The " + channels[channel].name + " is " + varbinds); }).bind(this, channel)); } 

而且你猜你的问题是由于访问channel中的callback,这是一个共享variables,并且在callback被调用的时候,你的for循环将会贯穿并且通道将保持从channels枚举的最后一个key

另一种方法是使用asynchronous模块 ,这样可以简化控制stream程,从而在引入更多的asynchronous调用时提高可读性。

 function pollOID() { for (channel in channels) { (function(channel){ session.get({ oid: channels[channel].oid }, function (varbinds) { console.log("The " + channels[channel].name + " is " + varbinds); }); })(channel); } 

 function pollOID() { var log = function(channel, cb){ session.get({ oid: channel.oid }, function (varbinds) { console.log("The " + channel.name + " is " + varbinds); cb(); // Moves onto next element in channels when cb is called }); }; var allDone = function(err, result) { // all tasks are complete }; async.each(channels, log, allDone); } 

async.each将并行运行,所以如果需要按顺序运行,请改用async.eachSeries