The way I've handled this in arc in the past - particularly for the JS version where you can't possibly avoid having to handle external events of various sorts - is to use a service that specifically acts as a proxy to the world outside the game loop. These services listen on the relevant event dispatcher(s) and stack up incoming events, which are popped off at the earliest opportunity by the controller class(es) (the main actors of the game loop in arc and can access any service) and handled thereby. You could handle one or more such events in a single game loop frame.
Using services neatly keeps this code away from your main game logic which - as you rightly indicate - shouldn't be polluted by external event loops.
One thing I will say about this is that if receiving game state from a server or peer, you will want those events to represent deltas, not absolute state since it becomes that much harder to update your local data model if you have to compare the last and current state objects (i.e. the events) just in order to determine what has changed... caused me some initial headaches.
This was tested in production for a client's real-time app, so I imagine it would work fine for you.