使用 Protobuf.js ,我需要将多个异步调用的结果组合到一条消息中,然后将其作为答案发送。异步调用的顺序无法事先确定。我创建了一个示例脚本,该脚本调用了三个假设的远程服务:一个返回有关天气情况的消息,一个返回时间,另一个返回位置。
可能调用的顺序是随机的,或者再次,并非必须调用所有三个服务。为了合并结果,我一直跟踪调用的顺序,然后等待所有调用返回,对各种返回消息进行解码,然后将所有内容重新组合为一个新对象,然后进行相同的编码。
在我看来,这是一个非常麻烦的过程,会增加此类操作的延迟。您是否有任何建议来简化该过程并使它更有效?
这是示例脚本:
const protobuf = require("protobufjs");
const proto = `
syntax = "proto3";
message Location {
string city = 1;
string zip = 2;
}
message Weather {
string condition = 3;
string temperature = 4;
}
message Time {
string day = 5;
string year = 6;
}
message AllMetadata {
optional Location location = 7;
optional Weather weather = 8;
optional Time time = 9;
}`;
const root = protobuf.parse(proto, { keepCase: true }).root;
const locTmp = root.lookup("Location");
const weaTmp = root.lookup("Weather");
const timeTmp = root.lookup("Time");
const allTmp = root.lookup("AllMetadata");
const asyncCall = (tmp, msg, timeout) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
let ret = tmp.encode(msg).finish();
resolve(ret);
}, timeout);
});
};
const test = async () => {
let metaWorkers = [];
let callOrder = [];
let ret = {};
const add = (name, tmp, fnc) => {
metaWorkers.push(fnc);
callOrder.push({ name, tmp });
};
add(
"weather",
weaTmp,
asyncCall(weaTmp, { condition: "cloud", temperature: "20" }, 100)
);
add(
"location",
locTmp,
asyncCall(locTmp, { city: "rome", zip: "00152" }, 150)
);
add(
"time",
timeTmp,
asyncCall(timeTmp, { day: "sunday", year: "2019" }, 200)
);
let results = await Promise.all(metaWorkers);
results.forEach((res, i) => {
let { name, tmp } = callOrder[i];
ret[name] = tmp.decode(res);
});
let enc = allTmp.encode(ret).finish();
return enc;
};
test().then(data => console.log(allTmp.decode(data)));