0

Being new to Node, I am still having some troubles with callbacks.

In the mapBpiIfindex function I am trying to loop through all of the VLANs found by the vlans function. Once it has looped through all VLANs, creating the map, I want to output the map to the browser. But, the only output I am getting is {}. How can I send the mapping to the browser? I am not even sure if I am using my callbacks correctly.

var express = require('express');
var router = express.Router();
var snmp = require('snmp-native');


// Create a Session with explicit default host, port, and community.
let session = new snmp.Session({ host: 'AASW0120', port: 161, community: 'community' })

let Mibs = {
    hostname: [1,3,6,1,2,1,1,5,0],
    vlans: [1,3,6,1,4,1,9,9,46,1,3,1,1,2],
    dot1dBasePortIfIndex: [1,3,6,1,2,1,17,1,4,1,2]
}


/* Get all VLANs on switch */
function vlans(snmpSession, cb) {
    let vlans = []
    session.getSubtree({ oid: Mibs.vlans }, function (error, varbinds) {
        if (error) {
            console.log('Fail :(');
        } else {
            varbinds.forEach(function (varbind) {
                vlans.push(varbind.oid[varbind.oid.length -1])
            })
        }
        cb(vlans)
    })
}


/* Map BPIs to Ifindices */
function mapBpiIfindex(session, cb) {
    let map = {}
    vlans(session, function (vlans) {
        vlans.forEach(function (vlan) {
            session.getSubtree({oid: Mibs.dot1dBasePortIfIndex, community: 'community@' + vlan}, function (error, varbinds) {
                if (error) {
                    console.log('Fail :(')
                } else {
                    varbinds.forEach(function (varbind) {
                        map[varbind.oid[varbind.oid.length -1]] = {ifindex: varbind.value, vlan: vlan}
                    })
                }
            })
        })
        cb(map)
    })
}



router.get('/vlans', function (req, res, next) {
    vlans(session, function (vlans) {
        res.send(vlans)
    })
})

router.get('/bpi-ifindex', function (req, res, next) {
    mapBpiIfindex(session, function (mapping) {
        res.send(mapping)
    })
})
ChaChaPoly
  • 1,811
  • 5
  • 17
  • 39

1 Answers1

1

The answer is no, youre not using it correctly ;) A few things here:

  1. You should be clear that only the code within the callback is executed after the operation has finished, so cb(map)does not wait until all youre looped callbacks have finished. Thats why nothing is returned (because when cb is called, the async functions have not finished yet and map values are undefined. Have a look at this How do I return the response from an asynchronous call?, its the same principle.

  2. Have a look at async module. Specifically, the do* or whilst methods. It'll help you process loops with async function calls.

  3. Apart from that, you should not use forEach if you mind about performance.

Community
  • 1
  • 1
FluffyNights
  • 294
  • 3
  • 6