Если вы здесь, потому что знаете, по крайней мере, что такое NodeJs и его основы, в противном случае я бы порекомендовал сначала проверить другой вводный материал, а затем вернуться снова, и, пожалуйста, не поймите меня неправильно, что вы собираетесь увидеть - это не сложная и сложная тема, но для правильного понимания концепции требуются определенные знания.

Таким образом, эту среду выполнения JavaScript можно использовать для прототипирования небольших PoC или даже для обработки больших распределенных приложений. Его природа состоит в том, чтобы запускать задачи асинхронно, потому что у него есть только поток для выполнения событий.

Цель этого поста - рассмотреть шаблоны обратных вызовов, CPS и то, как можно выполнять обещания и стратегию async / await для обещаний, а также параллельное и последовательное выполнение задач.

Давайте начнем с объяснения шаблона обратного вызова, который в основном представляет собой блок инструкций, заключенных в функцию после завершения асинхронного вызова. Этот первый фрагмент описывает обычную функцию синхронизации в JavaScript, которая выполняет регулярное выражение для преобразования найденной буквы, найденной в «X», в строку. Как только вы его вызываете, вы напрямую получаете преобразованный результат.

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

Итак, «Название CPS связано с тем, что вы всегда передаете обратный вызов в качестве последнего аргумента функциям», тогда этот обратный вызов продолжает выполнение функции, что является следующим шагом.

Может быть другой подход с использованием process.nextTick, это указывает Node напрямую вызывать функцию в следующем цикле, в двух словах, асинхронное выполнение.

Просто обратите внимание, что console.log('end') будет выполняться до, а затем после следующего цикла выполняется обратный вызов.

Большой.

JS обещает

Естественная эволюция обратных вызовов - это обещания, которые устанавливают объект, который представляет окончательное завершение асинхронных операций, независимо от результатов (успешных или нет).

Формальное определение устанавливает, что «Promise является прокси для значения, не обязательно известного на момент создания обещания. Он позволяет связать обработчики с конечным значением успеха или причиной сбоя асинхронного действия ».

Это позволяет асинхронным методам возвращать значения, как синхронные методы: вместо того, чтобы немедленно возвращать окончательное значение, асинхронный метод возвращает обещание предоставить значение в какой-то момент в будущем.

Итак, вместо того, чтобы выполнять простой обратный вызов, подобный этому

Вы реализуете более строгую структуру, которая будет обрабатывать успех (разрешение) и ошибку (отклонение) более эффективным и разумным способом.

Правильное понимание этого может занять некоторое время, по моему опыту, этот «переход» был совсем не легким.

Обещать

Хорошо, еще один механизм - это функция Promisify, которая определена в модуле Util узла как стандарт, и ее цель - преобразовать обратный вызов в обещания, не более того.

Формально этот параметр используется для преобразования метода, возвращающего ответы, с помощью функции обратного вызова для возврата ответов в объекте обещания. Итак, вместо того, чтобы делать это, первую часть блока (по старинке), вы можете выполнить преобразование обещания с помощью всего двух строк кода.

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

Асинхронный / Ожидание

JavaScript эволюционировал (фактически, некоторое время назад), и они предоставили нам подход async / await. Этот механизм дает нам возможность работать с обещаниями по-другому, по сути, вы увидите код, который выглядит «синхронизированным», но система будет «ждать», пока все не будет выполнено. У вас может быть много «ожиданий» для одной «асинхронной» функции.

Для этого рекомендуется поместить выполнение в песочницу в try/catch statement.

Вот пример

Этот пример довольно прост, обещание delay работает с функцией async, и в зависимости от ответа if / else, раздел или элемент resolve будут напечатаны внутри функции setTimeout. Результат будет примерно таким: Case executed: Great.

Параллелизм с обещаниями

Промисы могут обрабатывать параллельное выполнение с помощью Promise.all в форме массива промисов.

Вот фрагмент, который это демонстрирует.

В нем используется модуль fs узла для записи трех файлов в текущий каталог выполнения. Он использует promisify для работы с объектом Promise.all.

Я также обнаружил, что этот расширенный пример работы Promises для достижения определенного типа выполнения параллелизма, основанный на массиве tasks, который является обещанием, отложенным на setTimeouts, и настраиваемом классе PromiseQueue, который реализует стратегию FIFO, основное выполнение - это печать значения X, пока итерация продолжается до тех пор, пока не будет остановлена.

Протестируйте и проверьте, как это работает.

Доминируя над асинхронными задачами, вы получите полный контроль над поведением своей программы, асинхронная работа стала одной из основных основ, которые NodeJs предлагает для современных приложений. Чем больше становится блокировок, тем хуже для пользователей. Конечно, многие разумные исключения не могут быть обработаны с помощью асинхронных шаблонов.

Следующая естественная тема, которую нам нужно затронуть, чтобы полностью освоить асинхронные задачи, - это потоки данных (в общем), поэтому следующий пост будет об этом.

Счастливого асинхронного :)