
Let me lead off with the question, then present the context (you tell me if I'm even asking the right question)... Do I need to use a promise to read the notes property of a handout object? And, if so, do I need to wrap all subsequent code in a .then() block? In other words, does getting information from the notes of a handout suddenly require me to turn all of my code asynchronous... or can I handle this in a callback and call it a day? Here's what I'm trying to do... for a script, there could be a game-wide configuration handout and/or a speaker-level configuration handout. The script should look to see if there is a speaker-level configuration (the most specific), and if it doesn't see that it should look for a game-wide configuration, and if it doesn't find that, it should read its own default internal configuration. In game, this might mean that the GM has set up a game-wide look for certain interactions, but the players might have set up specific configurations for their characters. I can get the notes out of the config handout, but the way I have it written right now (with a promise) makes it wait to resolve until the rest of the active stack gets resolved. So, using the revealing module pattern, my script runs handleInput (not yet wrapped in a then() block): const handleInput = (msg_orig) => {
if (msg_orig.type !=="api") return;
let apicatch = "", xr = "xr", ia = "ia", vw = "vw";
if (new RegExp(/^!xray\s/).exec(msg_orig.content.toLowerCase()) !== null) apicatch = xr;
else if (new RegExp(/^!insertarg(\s|s\s)/).exec(msg_orig.content.toLowerCase()) !== null) apicatch = ia;
if (apicatch === "") return;
let args = msg_orig.content.split(/\s--/)
.slice(1) // get rid of api handle
.map(splitArgs) // split each arg (foo:bar becomes [foo, bar])
.map(joinVals); // if the value included a colon (the delimiter), join the parts that were inadvertently separated
const abil = args.shift(); // assign the first arg to abil
let cmdline = "";
let theSpeaker = getTheSpeaker(msg_orig);
let configObj = getConfig(theSpeaker);
log(`===== CONFIG ===== `);
log(configObj);
/* other stuff happens */
sendChat(...........)
return;
};
The getConfig() function looks like this: const getConfig = (theSpeaker) => {
let cfgObj = { table: menutable, row: menurow, bg: "#ff9747", css: "" };
let cfgho = findObjs({ type: "handout", name: `IAConfig-${theSpeaker.localname}` })[0] || // get the config for this player/character, if present
findObjs({ type: "handout", name: "IAConfig-Global" })[0] || // if no specific config, look for global
{ get: () => { return ""; } }; // if no config exists, return an object with a single method
let cfgtext = "";
let ConfigNotes = new Promise((resolve, reject) => { cfgho.get('notes', (notes) => { resolve(notes); }); });
ConfigNotes.then((result) => {
cfgtext = result;
// get table components into the configObj
let m = new RegExp(/(<!--\sBEGIN\sTABLE\s-->.*?<!--\sEND\sTABLE\s-->).*?(<!--\sBEGIN\sROW\s-->.*?<!--\sEND\sROW\s-->)/, 'gmi').exec(cfgtext);
// group 1: table delimited by table tags from tablerow
// group 2: row delimited by row tags from tablerow
if (m) Object.assign(cfgObj, { table: m[1], row: m[2] });
// get config components into the configObj
m = new RegExp(/(<!--\sBEGIN\sCONFIG\s-->.*?<!--\sEND\sCONFIG\s-->)/, 'gmi').exec(cfgtext);
// group 1: config section delimted by config tags
if (m) {
let settings = ["css", "bg"], // settings available in the config section
sdata; // to hold the data from each setting read out of the config
settings.map((s) => {
sdata = new RegExp(`/^ --${s}#(.*?) \n/`, 'gmis').exec(m[1]);
//group 1: user input for the setting from --setting#user input
if (sdata) cfgObj[s] = sdata[1];
});
}
log(`During Promise: ${result}`);
return cfgObj;
});
};
This plan doesn't work. With things like this, my Promise doesn't resolve until after all of the synchronous code finishes. Even though the log line during the promise does have the correct data in it (the notes from the handout object), it doesn't run until after the handleInput has blown on by. My log looks like this: "===== CONFIG ===== "
undefined // <=== log(configObj)
"During Promise: ..... /* data from notes */ ..... // <=== log() during promise Does this mean that everything downstream of the getConfig() call has to be wrapped in a then() block? Or can the waiting on the asynchronous get('notes') happen in the callback? (I think I tried that but didn't get it to work.)