Я потратил большую часть прошлого года на программирование в Silverlight, а это значит, что я потратил много времени на обдумывание (и борьбу с) тех же проблем, которые вы описываете.
Вкратце, как указывали другие люди, реальная сила асинхронной модели заключается в ее способности создавать надежные системы, которые хорошо взаимодействуют с реальным миром. Никто не может реально использовать приложение Silverlight (или Flash), если поток пользовательского интерфейса останавливается каждый раз, когда для возврата вызова веб-службы требуется несколько секунд.
Самым большим недостатком является то, что полученный код сложен и его трудно устранить. Такие вещи, как обработка ошибок, являются PITA, но самая раздражающая вещь, с которой мне приходилось сталкиваться, это координация ответов от нескольких асинхронных вызовов. Если, скажем, вам нужна информация из вызова A перед выполнением вызова B, и вам нужна информация из вызова B перед выполнением вызова C (и т. Д.), Результирующий код выглядит действительно неприятно и подвержен всевозможным странным побочным эффектам. , Существуют методы, позволяющие заставить все это работать, и даже достаточно чисто, но если вы пришли из синхронного мира (как я), это значительная кривая обучения. (И это не помогает, что Microsoft выдвигает события как способ обработки вызовов WCF, когда обратные вызовы, на мой взгляд, намного чище и менее восприимчивы к таким странным побочным эффектам, о которых я говорил.)
(И да, другие люди правы, говоря, что это не язык, который является асинхронным настолько, насколько конкретные структуры требуют построения вашего кода асинхронным образом - но я понимаю, что вы имеете в виду.)
Обновление 2014.09.23 -
Я проделал гораздо больше работы с различными асинхронными средами, поскольку написал ответ выше (как, наверное, все остальные, кто занимался веб-кодированием), и решил добавить несколько дополнительных случайных заметок:
Если вы используете такой язык, как C # или F #, который имеет первоклассную асинхронную поддержку, многое из этого становится намного проще, по крайней мере, после того, как вы обернетесь вокруг странного async
/ await
шаблонов. Возможность легко зацикливаться на асинхронных вызовах и оборачивать все это простым try/catch
, удивительно, если вам когда-либо приходилось делать это по-старому.
Если вы не используете язык с первоклассной асинхронной поддержкой, начните использовать любую поддержку promise
или future
или task
, которую обеспечивает язык (например, $.Deferred()
в JQuery или $q.defer()
от Angular. Они намного чище и обеспечивают лучшую структуру, чем то, что вы обычно получаете с обратными вызовами.
Асинхронный код имеет решающее значение для написания масштабируемых серверных систем. Одна из самых больших проблем при правильном масштабировании типичного веб-сервера заключается в том, что он начинает исчерпывать потоки, по крайней мере, если он выделяет поток для достижения входящего запроса. Если этот поток останавливается, потому что он ожидает завершения длинного синхронного вызова, он полностью недоступен для помощи с чем-либо еще. Гораздо лучше сделать код вашего веб-сервера асинхронным, чтобы при ожидании возврата из БД этот поток мог обслуживать еще полдюжины других запросов, пока БД работает и выполняет любые действия БД. На данный момент для хорошо масштабируемых систем async - единственная игра в городе. (Просто спросите любого поклонника Node.)