Is there any way to programmatically detect if a context store requires asynchronous access?
Having to to handle multiple context variables is a complete pain if you have to take async access into account. The easiest way probably being to wrap the access requests in promises so that you can use Promise.all to continue your processing once all of the variables have been read.
For the most part, everyone seems to mostly assume that async access isn't required and just ignore it. Obviously though, this is not ideal.
So ideally, it would be best if we could have an API call that returned whether or not the store was async - does that exist? If not, could it be made to happen?
2nd best would be a promisified version of at least get functions to allow multiple gets to be waited on before continuing processing.
Or maybe there is an alternative that I've missed?
As a secondary request, would it be possible to adjust RED.util.evaluateNodeProperty for context variables to make the callback optional rather than required? If we know we don't need to handle async stores, it would make coding a lot simpler.
I have no hands-on experience, but looking at the documentation for ContextStore.get(scope, key, [callback]) the description says
If no callback is provided, and the store supports synchronous access, the get function should return the individual value, or array of values for the keys. If the store does not support synchronous access it should throw an error.
That suggests that a try... catch around a get with no callback should give you an answer.
Doh! I missed that, thanks. Obvious short term fix anyway. Though it doesn't really help with the overall issue of suddenly having to deal with a bunch of callbacks inside your message handler function. For now, I think I'm just going to error out if this is the case and come back to it when I can get my head around the convoluted processing.
That makes the code a lot more complex though annoyingly since I now have to move the msg processing into the callback.
OK, that's a point. I'll have to play with that to find out how it actually returns the data and confirm that it doesn't complete until all have returned. Thanks, I think that's the best option so far.
Yes, I realise that but while that lets me do Promise.all, it is still a lot more complex and still twists the processing into an async chain which is annoying.
That's a good idea - but maybe not so simple. I've had a couple of goes at creating one but kept getting lost in the various processes. Not enough time to work it all out.
Thanks all, I think that having a single call with multiple keys - assuming it works, is going to be easiest.
Well, even the original author explained that it should never really have seen the light of day. Having been written in a hurry to prove a point. For all its foibles, Python would have been a better choice for the language of the web.
Maybe someone needs to ask ChatGPT about creating a new language for the web.
Actually, that's kind of how I started programming. Because COBOL was such a pain to write, Phillips had a minicomputer system where we wrote "pseudo-code" and it translated into COBOL which was then compiled - go figure!
Then later, I moved on to so called "4th generation languages", a system called "Focus" allowed us to write "natural" language queries against databases. Had the interesting trait where the query would sometimes not work so you walked back through the query to the beginning and it still wouldn't work but then you but all the same text back and it would work. Fun debugging!
Annoyingly, this isn't feasible in the case where you have multiple typedInput fields because the RED.util.evaluateNodeProperty does NOT have the ability to process multiple inputs. So the code continues to get more complex.
In the end, I tried Steve's promisify approach and had to make my msg input handler async all the way down.
Oddly, I tried to promisify RED.util.evaluateNodeProperty in the same way suggested for flow/global.get but I couldn't get it to work no matter what I tried - this is the simple version but I tried some more and less complex versions too: