There are two ways to call a script and they have different behaviours. One waits for the script to complete before executing the next action. The other method does not. See: Scripts - Home Assistant
As far as I know, synchronous mode is the default mode for almost everything a user might touch in HA (actions, scripts, automations, etc.). Asynchronous doesn’t mean parallel execution, but “yielding”. Whenever you use the -delay or -wait_for_* action, that’s yielding. So the whole picture is synchronous execution, jumping from one fragment to another, managed by some internal scheduler.
That’s why I think, the async behaviour you see is probably caused by “yielding” code contained in your switch.
Most actions have to be completed before moving to the next. With some exceptions, e.g. explicitly using parallel mode or the second script call method shown in the link I shared above.
i.e. we use turn_on / turn_off of a switch and we start clicking to see the results…
when you put a delay (or more delay) somewhere in the code turn_on and turn_off continue to run, even if you change the state of the switch, and things messes up fast; the result is unpredictable