所有,
试图让我的周围封锁头在node.js的上下文(异步调用)。
我有以下代码:
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数据使用第二个在回调的setInterval一个循环来查询几个SNMP实体路由器的路由器。 该session.get函数有一个异步回调来处理来自路由器的结果。
该SNMP位工作正常,我的问题是关于如何坚持对话异步回调内部循环变量通道的值。
我得到如下结果:
The Download Attenuation is 7.5
The Download Attenuation is 361600
The Download Attenuation is 60
所以循环变量信道改变用于每个调用session.get作为函数返回从路由器正确的值。 我的问题是通道[频道]。名称使用其中由时间回调返回循环已经结束,并且信道是2(第三环,其是名称的字符串“下载衰减”)信道的当前值。 所以,我需要来持久session.get回调它是当回调被调用,以便正确的频道[频道]。名称在session.get回调中使用的值的内部信道的值。
我知道我必须使用一个封闭的这一点,但尝试了许多不同的方法,我不能让它正常工作后。 任何线索指向我朝着正确的方向吗? 谢谢!
你可以创建一个简单的封闭扶住的本地副本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);
}
或者你也可以使用绑定的参数传递,但上下文将回调里面,虽然改变。
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
中,是一个共享变量的回调和回调调用你的循环将通过已经运行和渠道将举行最后时刻key
的列举channels
。
另一种方法是使用异步模块 ,并且这简化了随着更多的异步调用被引入能够提高可读性控制流程。
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
代替。