NodeJS Async/Await 或 Promise for net-snmp 模块

NodeJS Async/Await or Promise for net-snmp module

请有人帮忙,我就是搞不懂。 您能否帮助说明如何制作 async/await 或承诺 (doneCb),以便脚本首先等待 vlc_snmp(..) 完成然后调用下一个? 示例:

function doneCb(error) {
  console.log(final_result);
  final_result = [];
  if (error)
    console.error(error.toString());
}

function feedCb(varbinds) {
  for (var i = 0; i < varbinds.length; i++) {
    if (snmp.isVarbindError(varbinds[i]))
      console.error(snmp.varbindError(varbinds[i]));
    else {
      var snmp_rez = {
        oid: (varbinds[i].oid).toString()
        value: (varbinds[i].value).toString()
      };

      final_result.push(snmp_rez);
    }
  }
}

  var session = snmp.createSession(VLC_IP, "public", options);

  var maxRepetitions = 20;

  function vlc_snmp(OID) {
    session.subtree(OID_, maxRepetitions, feedCb, doneCb);
  }

 vlc_snmp(OID_SERIAL_NUMBER);
 //wait OID_SERIAL_NUMBER to finish and then call next
 vlc_snmp(OID_DEVICE_NAME);

您应该能够使用 async / await 语句来等待完成的回调被调用。我们将此回调包装在 vlc_snmp 函数和 return 一个 Promise 中。这允许我们使用 await 语句。

我模拟了一些我无法访问的代码,它的行为应该与真实代码有些相似。

这里的关键点是,当函数 return 是 Promise 时,我们可以 await 异步函数中的结果,这将为您提供您想要的行为。

final_result = [];
const VLC_IP = "";
const options = {};
const OID_ = "OID_";
const OID_SERIAL_NUMBER = "OID_SERIAL_NUMBER"
const OID_DEVICE_NAME = "OID_DEVICE_NAME"


// Mock out snmp to call feedcb and donecb
const snmp = { 
    createSession(...args) { 
        return {
            subtree(oid, maxRepetitions, feedCb, doneCb) {
                setTimeout(feedCb, 500, [{ oid, value: 42}])
                setTimeout(doneCb, 1000);
            } 
        }
    },
    isVarbindError(input) { 
        return false;
    }
}

function doneCb(error) {
  console.log("doneCb: final_result:", final_result);
  final_result = [];
  if (error)
    console.error("doneCb: Error:", error.toString());
}

function feedCb(varbinds) {
  for (var i = 0; i < varbinds.length; i++) {
    if (snmp.isVarbindError(varbinds[i]))
      console.error(snmp.varbindError(varbinds[i]));
    else {
      var snmp_rez = {
        oid: (varbinds[i].oid).toString(),
        value: (varbinds[i].value).toString()
      };

      final_result.push(snmp_rez);
    }
  }
}

var session = snmp.createSession(VLC_IP, "public", options);

var maxRepetitions = 20;

function vlc_snmp(OID) {
    return new Promise((resolve,reject) => {
        session.subtree(OID, maxRepetitions, feedCb, (error) => {
            // This is a wrapper callback on doneCb
            // Always call the doneCb
            doneCb(error);
            if (error) { 
                reject(error);
            } else { 
                resolve();
            }
        });
    });
}

async function run_vls_snmp() {
    console.log("run_vls_snmp: Calling vlc_snmp(OID_SERIAL_NUMBER)...");
    await vlc_snmp(OID_SERIAL_NUMBER);
    console.log("run_vls_snmp: Calling vlc_snmp(OID_DEVICE_NAME)...");
    //wait OID_SERIAL_NUMBER to finish and then call next
    await vlc_snmp(OID_DEVICE_NAME);
}
 
run_vls_snmp();