Async: false; — плохая практика?
В браузере в одном потоке выполняется и Ваш JS и интерфейс пользователя и много чего еще. И если Вы заблокируете этот поток длинными вычислениями или еще чем-то, то все это встанет. Для пользователя вкладка зависнет. Не будут работать ни ссылки, ни кнопки, даже закрыть ее привычными способами будет проблематично.
Синхронный запрос блокирует поток на время всей отправки запроса и получения ответа, притом именно так, поочереди, ибо враз тут опять не выйдет. Добавьте сюда еще то, что сеть обычно штука медленная.

mutation observer ловит изменения, делает проверку и заполняет массив потоми делает запрос. Но тут почему то ajax не ждёт пока заполнится массив и сразу выполняет запрос.К тому же эту проблему синхронный запрос не решит, он ее наоборот усугубит, так как MutationObserver так же не сможет отработать пока не завершится запрос.

Существуют ли случаи, когда оправдано использование синхронных запросовединственное оправданное применение - отправка данных перед закрытием вкладки на динозаврах без поддержки sendBeacon
Заметьте, в современном fetch api даже нет такой возможности, как отправка синхронного запроса, и не просто так.

логика хромает и лучше всего все переписатьк сожалению появление асинхронности в одном месте может привести к появлению асинхронности во многих других местах, по другому ни как. Так что да, придется переписать. Но это неизбежно, так как многие api в современно браузере (тот же MutationObserver) работают только асинхронно. К счастью есть промисы и async/await сахар над ними, что сильно упрощает такую задачу.
Если выполнить синхронный Ajax-запрос, пользовательский интерфейс JS-приложения окажется заблокированным. Пользователь не сможет щёлкнуть по кнопке, ввести данные в поле, он не сможет даже прокрутить страницу. Синхронное выполнение Ajax-запросов не даст пользователю взаимодействовать с приложением. Такой подход хотя и возможен, но приводит к катастрофическим последствиям.