问题描述
请有人帮忙,我就是无法得到它。 你能帮助我如何制作 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();