Как стать автором
Обновить

Символы, генераторы, async/await и асинхронные итераторы в JavaScript: их сущность, взаимосвязь и варианты использования

Время на прочтение23 мин
Количество просмотров33K
Всего голосов 43: ↑40 и ↓3+37
Комментарии14

Комментарии 14

На самом деле, до появления типа данных symbol сделать этого было нельзя.

На самом деле можно:


Object.defineProperty(myObject, 'newProperty', { value: ..., enumerable: false});
Ваш цикл статей по JavaScript'у — просто сказка.
>Какие технологии, освещённые в этом материале, вы используете на практике?
Символы и генераторы активно использовал в начале, но перестал. Единственное практическое применение для символов, что я нашел, это хранение метадаты, что нужно не часто. Для других целей, замусоривает код, а какой то однозначной пользы особо нет.
Генераторы, код слишком тяжело читать и соответственно поддерживать. Так же, для теории, я бы упомянул о yield* который позволяет «распаковывать» генератор внутри генератора, но использовать его я бы не рекомендовал, это усложняет код еще больше.
async/await тут вряд ли кто то будет спорить — гениальная вещь. Не хватает встроенной возможности отменять уже запущенные асинхронные операции, надеюсь это когда то добавят (или уже?).
НЛО прилетело и опубликовало эту надпись здесь
Прямое применение генераторов — ленивые трансформации последовательностей. Иногда бывает намного проще написать пару циклов и условных операторов чем ломать мозг над композициями трансдьюсеров.

Еще генераторы применяются вместо async/await в тех случаях когда стандартного поведения не достаточно и нужно выполнять дополнительную инициализацию перед началом выполнения каждого асинхронного продолжения.

Раздельная многозадачность, конечные автоматы и пр. это скорее какое-то специфическое применение генераторов. Стандартное — просто итерирования коллекций. Например, если вы работали с jQuery, то вот: for(const $node of $results) ;, где в $.fn[Symbol.iterator] задан нужный метод (удобнее использовать генераторы из-за сахара), который будет лениво обрамлять каждый под-элемент $()-обёрткой.


Довольно много проектов, особенно backend, завязаны на различные трансформации одних цепочек данных в другие, самыми причудливыми способами. И там бывают самые причудливые коллекции. Да те же stream-ы из nodejs, к примеру, и те можно как-нибудь заитерировать (for await of).


Т.е. в основе лежит вопрос не "зачем нужны генераторы", а вопрос "зачем нужен универсальный протокол итерирования", да ещё и ленивый. Ответив на него — легко ответить на первый вопрос — генераторы это сахар для итераторов.


Ну а так как генераторы потянули за собой существенные изменения в самом JS, то им нашли и разные нестандартные применения. Особенно лихой — замена async/await. Да и redux-saga отличились.

В ES2015 появился новый, шестой тип данных — symbol.

Лучше перефразировать в "… новый, шестой примитивный тип данных...", потому что по факту он не шестой, а седьмой.
Причина №2. Символы уникальны
Эта «причина», мне кажется, показывает глубокое индусских разработчиков понимание различия между именем свойства и его значением.
Что, скажите, поменяется, если вместо
var includes = Symbol('will store custom includes method');

написать
var includes = 'will store custom includes method';

??
Да почти ничего:
...
//А здесь мы вызываем наш собственный метод includes
arr[includes](); // 'inside includes func', так как includes - это с̶и̶м̶в̶о̶л̵ строка
Обычная строка работает только до тех пор пока другая библиотека не захочет взять себе такую же. Причем хитрости вроде добавления названия библиотеки не спасут, ведь простейший способ организовать конфликт — загрузить две разные версии одной и той же библиотеки (да, так бывает! Я лично видел 4 экземпляра jquery на одной странице).

Поможет сделать строки уникальными, разве что, добавление случайного числа или глобального автоинкрементного счетчика — но, как по мне, больно некрасивый костыль получается. Для полифилов сойдет, но для написания нормальных библиотек символы лучше.
Ну если в исходном примере додумаются использовать Symbol.for() вместо Symbol(), такая же фигня получится. А ведь додумаются же…

И я в любом случае имел в виду использование имени переменной вместо значения свойства или строки в [скобках], поданое как что-то равнозначное и доселе невиданное.
Поэтому можно говорить о том, что поведение Symbol.for напоминает шаблон проектирования синглтон.

По-моему, все-таки тут фабричный метод. Так как при разных значениях аргумента for мы получим разные значения, а синглтон всегда один

НЛО прилетело и опубликовало эту надпись здесь
Правильно бы назвать это Multiton

Отличная статья!

Зарегистрируйтесь на Хабре, чтобы оставить комментарий