If i read you the right way, then the function is not the problem.
It should not be too. Because functions act as they are 'in place'. Replace the 'function call' with the contents of the 'on function' and nothing is changing. Read 'as in place'.
The problem is the way you use Ajax (educated gamble).
If this is what happens .....
On function (sync group)
____ Get ajax data
____ Set something to last Ajax data
____ Bunch of actions dealing with the data
On function (UI group)
____ Get ajax data
____ Set something to last Ajax data
____ Bunch of actions dealing with the data
Then... As you stated, getting Ajax data is not instantly. It takes time.
So, the last Ajax data are for sure not ready to use in the scope of this function call.
At some time, one of those functions is called again, and there will be data from some previous request data action.
From which request action is totally not known, and cant be known, that way.
It is obvious not the way to use Ajax. To avoid asynchronous blending, the Ajax requests are paired up with a tag.
To know which data are in the last data, and to know when the data are ready to use, you have the condition 'On completed (tag)'.
Or 'On any completed' , and the expression Ajax.tag is returning the tag.
I suggest to call the function, request data in the 'on function' with a tag "sync" or "UI".
Have a root event 'On any completed'
Have a sub with a compare 2 values. Compare Ajax.tag to "sync"
Set something to last data and do the stuff that belongs to "sync"
Use 'else' or a compare for "UI"
Set something to last data and do the stuff that belongs to "UI"
That would be the basic stuff. But now, those darn users could be multitasking. And you dont know which "UI" stuff belongs to which 'user call'.
Well, user needs to be identified. By example. Give each user an array. Give the array a instance variable with a value that is unique for that user, so you can pick it easy.
Now call the "UI" function with a parameter holding that user id.
Request Ajax data with a tag "UI"&"/"&user id
If you now use the 'On any completed' as a root.
then compare 2 values ... tokenat(Ajax.tag,0,"/") = "UI"
then pick array with instance variable 'id' = tokenat(Ajax.tag,1,"/")
____ store the last data in that array
____ do stuff with the data all you want
____ update the information to the user straight a head, or 'signal' the postponed action by a 'wait for signal' right after the function call made by the user
Hope that makes sense to you.