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