TL;DR.

Заголовок Clickbait. Асинхронные генераторы - отличная новость, но вы не можете выбрасывать потоки преобразований в корзину.

Что такое потоки преобразования?

В документе Node.js говорится: «поток преобразования - это дуплексный поток, в котором выходные данные каким-либо образом вычисляются из входных данных. Примеры включают потоки zlib или криптопотоки, которые сжимают, шифруют или дешифруют данные ».

Я не буду здесь их объяснять, в Интернете можно найти множество бесплатных ресурсов. Это действительно мощный ресурс для создания удивительных вещей с помощью Node.js, но недостатком является то, что их не так просто реализовать даже для простых вещей. В любом случае, если вам нужно обрабатывать только логику преобразования фрагментов, скорее всего, этот тип потоков является лучшим.

Потоки преобразования - это независимые единицы в нашем коде, они могут напрямую передаваться по конвейеру с другими потоками, используя все преимущества случая. Обратное давление будет применяться автоматически, поэтому нам не нужно беспокоиться о разнице во времени между читаемым и записываемым потоками. Node.js оптимизирует эти процессы, сделав их параллельными.

Как в игру вступают асинхронные генераторы?

Асинхронные генераторы - это особая новость ES9, которая позволяет нам легко реализовать интерфейс асинхронного итератора. В потоках Node.js это уже реализовано, что позволяет нам делать следующее:

Итак, если поток доступен для чтения, он также является асинхронным итерабельным.

Это не учебник по асинхронным материалам, если вы хотите узнать больше об асинхронных итерациях и асинхронных генераторах, проверьте это!

Их можно использовать для преобразования фрагментов, таких как потоки преобразования, но их основная цель - обрабатывать поток данных.

Короче говоря, асинхронные генераторы позволяют:

Теперь время полностью под вашим контролем. Вам не нужно запрашивать данные из источника, как только они станут доступны. Вам не нужно записывать данные в поток записи, как только вы их получите от источника. Конечно, вы должны ждать каждый раз, когда вы запрашиваете данные и каждый раз, когда вы их записываете, потому что чтение и запись являются асинхронными операциями.

Дело в том, что то, что делать между чтением и записью, зависит от вас, и это может быть асинхронно. Было бы ложью, если бы я сказал вам, что вы не можете сделать что-то подобное с потоками преобразований. Но с асинхронными генераторами все проще, и вы можете позволить другим объектам в вашем коде управлять асинхронным потоком данных. Вот почему мы можем рассматривать асинхронные генераторы как инструмент управления потоком данных.

Давайте посмотрим на пример, в котором мы передаем два генератора по конвейеру для фильтрации всех четных чисел и увеличения на одно нечетное перед записью их в process.stdout. Числа асинхронно поступают из таинственного читаемого потока:

В этом примере нет явного управления потоком, потому что каждый асинхронный генератор просто использует все фрагменты как можно скорее. В IIAFE ничего не изменилось из-за третьего ожидания. Но асинхронную итерацию, возвращаемую конвейером асинхронных генераторов, можно было бы использовать по-другому, что дало нам возможность позволить другим объектам управлять всей асинхронной итерацией.

Вы не уверены в генераторах?

Не волнуйся. Я работаю над маленьким модулем, который позволит вам писать функции, в том числе асинхронные, а затем преобразовывать их в асинхронные генераторы! Кроме того, я написал небольшую вспомогательную функцию, чтобы легко объединить асинхронные генераторы.

Давайте посмотрим, как использовать asyncGeneratorsFactory:

Вы можете видеть, что функции фильтрации должны возвращать undefined только тогда, когда необходимо отбросить кусок. Нормальные функции преобразования всегда должны возвращать значение. Функции композиции пока не поддерживаются, но я над ними работаю.

Теперь давайте посмотрим, как подключить генераторы:

Это здорово, не правда ли?

Здесь вы можете найти полный gits.

Здесь вы можете увидеть исходный код моих помощников.

А как насчет производительности?

Я тестировал асинхронные генераторы и потоки преобразования с файлами. С файлами малого и среднего размера вы не увидите много различий: иногда потоки преобразования лучше, иногда генераторы async лучше.

Если вам нужно использовать мою вспомогательную функцию asyncGeneratorsFactory, знайте, что все пойдет немного медленнее.

В любом случае, с файлами большого размера кажется, что генераторы async лучше также для целей преобразования. Но необходимы дополнительные тесты и с разными типами потоков. Если можете, помогите мне :)