It turns out that DWR already has a solution to my asynchronous problems with AJAX:
DWREngine.setOrdered(true);
Turns out there is some really useful stuff in the Script Engine documentation; for instance you can set pre call and post call hooks to “wish to grey out certain components to prevent them being used again until the call returns”.
I'm actually using an older version of DWR that doesn't seem to support this – time to updgrade I guess.