用于 net-snmp 模块的 NodeJS Async/Await 或 Promise

问题描述

请有人帮忙,我就是无法得到它。 你能帮助我如何制作 async/await 或 promise (doneCb),让脚本先等待 vlc_snmp(..) 完成,然后再调用 next 吗? 示例:

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 语句来等待调用 done 回调。我们将此回调包装在 vlc_snmp 函数中,并返回一个 Promise。这允许我们使用 await 语句。

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

这里的关键是,当一个函数返回一个 Promise 时,我们可以等待异步函数中的结果,这会给你你想要的行为。

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,(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();