XMLHttpRequest has a synchronous version, where as fetch does not.
For instance, this means you can do an XMLHttpRequest in your app's router, and decouple your presentation from dealing with endpoints. Fetch can't do this.
That's an unjustified excuse. The one thing that is consistent with UI programming among all platforms is that you never block the UI thread.
You should be able to mock fetch/xmlhttprequest at any point, not just in your router. You should be able to mock those calls without needing to block the UI thread at runtime.
You mean unit testing? How so? I have never seen unit tests make real HTTP requests; it's much better to mock them. And changing from async to sync code for unit tests sounds like a bad idea, since you're not testing your code the way it actually works in production.
Your router could wait for async function and you could use await in your router's function, accomplishing the exact same thing but without blocking the main thread.
Functionally this is still very different from sync xhr. Changing from sync xhr to await+fetch will introduce new bugs into your application unless it was written carefully, because now code can run and interactions can happen during the fetch that would have been blocked by the sync xhr occupying the event loop.
Promises are also specced so that their handlers don't run until the event loop completes a turn, which means that no matter what there is now an opportunity for queued callbacks to run before you actually process the response to your request, even if it hit in-memory cache.
For instance, this means you can do an XMLHttpRequest in your app's router, and decouple your presentation from dealing with endpoints. Fetch can't do this.