Ответ 1
Я работаю почти с генераторами в течение месяца, так что, возможно, я могу нанести удар. Я постараюсь свести мнения к минимуму. Надеюсь, это поможет прояснить некоторые путаницы.
Отчасти из-за отсутствия лучших практик и более подробных объяснений это то, что эта функция все еще настолько новая в javascript. Есть еще очень мало мест, где вы можете использовать генераторы node.js и firefox, являющиеся наиболее заметными, хотя firefox немного отличается от стандартного.
Я хотел бы отметить, что есть такие инструменты, как traceur и регенератор, которые позволят вам использовать их для разработки и позволят вам превратить их в полуэквивалентные ES5, поэтому, если вы обнаружите, что работа с ними приятна, тогда нет причин не начинать используя их, если вы не нацеливаете архаичные браузеры.
Генераторы
Генераторы первоначально не воспринимались как способ обработки асинхронных потоков управления, но они прекрасно работают над ним. Генераторы - это, по сути, функции итератора, которые позволяют их выполнение приостанавливаться и возобновляться с использованием урожая.
Ключевое слово yield по сути говорит, что возвращает это значение для этой итерации, и я заберу, где я остановился, когда вы снова вызовите next().
Функции генератора - это специальные функции, поскольку они не выполняют первый раз, когда они вызывают, но вместо этого возвращают объект итератора с несколькими методами на нем и возможность использования в циклах for-of и array.
send(),: Это отправляет значение в генератор, обрабатывая его как последнее значение доходности и продолжает следующую итерацию
next(),: Это продолжит следующую итерацию генератора
throw(): Это генерирует исключение INTO генератора, вызывающего генератор, который генерирует исключение, как если бы оно было получено из последнего оператора yield.
close(): это заставляет генератор возвращать выполнение и вызывает любой окончательный код генератора, который позволяет при необходимости запускать окончательную обработку ошибок.
Их способность приостанавливаться и возобновляться - вот что делает их настолько мощными при управлении потоком.
Co
Co была основана на способности генераторов облегчить управление потоком обработки. Он не поддерживает все то, что вы можете делать с генераторами, но вы можете использовать большинство из них с помощью использования с меньшим количеством шаблонов и головной боли. И для целей управления потоком я не обнаружил, что мне нужно что-либо за пределами того, что предоставляет. Хотя, честно говоря, я не пробовал отправлять значение в генератор во время контроля потока, но это вызывает некоторые интересные возможности....
Существуют и другие библиотеки генераторов, некоторые из которых, которые я могу думать о моей голове, приостанавливаются и запускаются. Я пробовал их все, и сотрудничество предлагает большую гибкость. Приостановить может быть немного легче следовать, если вы еще не привыкли к генераторам, но я не могу сказать это с полномочиями.
Что касается node и лучших практик, я бы сказал, что co в настоящее время выигрывает руки с количеством инструментов поддержки, которые были созданы для этого. С приостановкой, скорее всего, занявший второе место.
Co работает как с promises, так и с thunks, и они используются для оператора yield, так что co знает, когда продолжать выполнение генератора вместо того, чтобы вы вручную вызывали next(). Co также поддерживает использование генераторов, функций генератора, объектов и массивов для дальнейшей поддержки управления потоком.
Получив массив или объект, вы можете выполнить параллельные операции над всеми получаемыми элементами. Уступив генератору или функции генератора, co будет делегировать дальнейшие вызовы новому генератору до тех пор, пока он не будет завершен, а затем возобновит вызов следующего по текущему генератору, что позволит эффективно создавать очень интересные механизмы управления потоком с минимальным шаблоном кода.
Promises
В то время как я сказал, что буду придерживаться мнения до минимума, я хотел бы сказать, что для меня promises, вероятно, самая сложная концепция. Они являются мощным инструментом для поддержания кода, но им трудно понять внутреннюю работу и могут приходить с довольно большим количеством ошибок при использовании для расширенного управления потоком.
Самый простой способ объяснить promises заключается в том, что они являются объектом, возвращаемым функцией, которая поддерживает состояние функции и список обратных вызовов для вызова, когда задано конкретное состояние объекта или был введен.
Обе библиотеки обещаний никуда не собираются в ближайшее время. Они добавляют много приятных для haves для promises включенных done(), которые не попадают в спецификацию ES6. Не говоря уже о том, что одни и те же библиотеки можно использовать в браузере, а в node мы будем использовать их в течение долгого времени.
санки
Thunks - это просто функции, которые принимают один обратный вызов параметров и возвращают другую функцию, которую они обертывают.
Это создает замыкание, которое позволяет вызывающему коду создавать экземпляр функции, передаваемой в своем обратном вызове, чтобы можно было сказать, когда этот метод завершен.
Thunks довольно прямолинейны, чтобы понять и использовать, по моему мнению, но они не являются правильным инструментом для всего. Например, spawn является основной болью для создания thunk, вы можете это сделать, но это нелегко.
Thunks vs. Promises
Они не являются взаимоисключающими и могут быть легко использованы вместе, но обычно лучше для вашего здравомыслия выбрать один и придерживаться его. Или, по крайней мере, выберите соглашение, чтобы вы могли легко сказать, что есть. Thunks работает быстрее из моего опыта, но я не сравнивал его. Большая часть этого, вероятно, связана с меньшей абстракцией и не имеет встроенных механизмов обработки ошибок.
Как правило, вы создаете что-то, что требует обработки ошибок, поэтому общая прибыль от выигрыша может легко или просто оказаться в стороне от promises в зависимости от вашего кода.
Когда использовать
Генераторы. Если вы можете с уверенностью сказать, что ваше приложение сможет работать на краю кровотечения, будь то firefox только для браузера или node > 0.11.3
Я использую их широко в компании, в которой я сейчас выхожу, и не мог быть более счастливым с механизмами потока управления и ленивой оценкой, которую они позволяют.
Promises против Thunks - это действительно зависит от вас и насколько вы комфортно работаете с каждым. Они не дают одинаковых преимуществ и не решают одну и ту же проблему. promises Помогите справиться с проблемой async напрямую, thunks просто убедитесь, что функция принимает требуемый параметр обратного вызова для другого кода, который должен пройти.
Вы можете использовать их обе вместе и до тех пор, пока вы можете сохранить их так, чтобы было очевидно, что у вас не будет проблем.
Promises/Thunks with Generators - я предлагаю сделать это в любое время, когда вы используете генераторы для потока управления. Это не обязательно, но проще, просто использовать co как абстракцию для управления потоком с генераторами. Меньше кода для ввода, упрощения обслуживания и меньших возможностей, которые вы попадете в крайний кейс, который еще кто-то еще не запустил.
Коа
Я не собираюсь подробно рассказывать о koa. Достаточно сказать, что это похоже на выражение, но написанное, чтобы воспользоваться генераторами. Это дает некоторые уникальные преимущества, такие как упрощение обработки ошибок и каскадное промежуточное программное обеспечение. Раньше были способы выполнить все эти задачи, но они были не изящными, а иногда и не самыми результативными.
Специальное примечание: Генераторы открывают дверь возможностей, которые мы еще не изучили. Точно так же, как они могут использоваться для управления потоком, когда это не был их первоначальный дизайн, я уверен, что они могут быть использованы для решения многих других проблем, с которыми у нас обычно возникают проблемы с javascript. Вероятно, это будут более яркие умы, чем я, которые узнают, как еще мы можем их использовать, но я, по крайней мере, начал бы играть с ними и лучше понимать, на что они способны. Еще больше преимуществ для генераторов, входящих в ES.next.