As a consequence of Issue , loops that try to find a large number of attributes in a large campaign take very long to complete, so long that the internal infinite loop detector goes off and the API goes down. Now, that's bad. I'm trying to circumvent that issue by performing all operations inside the loop in an asynchronous way. Now, I've been trying this (simplified version of the real deal, but that doesn't matter): list.forEach(function(charid) {
_.each(setting, function(attrValue,attrName) {
_.delay(setSingleAttribute, 1000, charid, attrName, attrValue);
});
}); Here, setSingleAttribute is the function that does all the expensive stuff (there's one findObjs call in each execution, plus possibly a createObj, plus setting that attribute to a value). This seems to work just fine if list is short. If list is very long (e.g. all characters in a 200+ character campaign with a lot of attributes from the sheet), it does manage to go through the loop successfully ... and then never seems to do any of the stuff inside setSingleAttribute (I've added a sendChat debug call inside setSingleAttribute, and that never gets sent to chat, not even once)? Then, after a while the API crashes with 'possible infinite loop detected'. Now, I've tried to do this with _.defer and setTimeout too, for the same effect. But then, I know nothing about JavaScript. Can this be done asynchronously in a way that does not crash the API? All the executions of setSingleAttribute are independent, and I really don't care when they finish or how long they take, just that they finish eventually without complaints by the API. Forum, can you help me? For reference, here are (again, simplified versions of) the functions called by the above loop. setSingleAttribute = function (charid, attrName, attrValue) {
let attr, current, max;
attr = myGetAttrByName(charid,attrName,createMissing);
if (attr) {
if (attrValue.current !== undefined) {
attr.set('current', attrValue.current);
}
if (attrValue.max !== undefined) {
attr.set('max',attrValue.max);
}
}
},
myGetAttrByName = function(charid, attrName) {
let attr = findObjs({type: 'attribute', characterid: charid, name: attrName}, {caseInsensitive: true})[0];
if (!attr) {
attr = createObj('attribute', {characterid: charid,name: attrName});
}
return attr;
},