JavaScript Async - спаситель от ада обратных вызовов / пирамиды гибели

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

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

JavaScript дает нам ключевое слово async и позволяет писать асинхронный код, читаемый как синхронный.

Происхождение показывает, куда что-то ведет

Async-Await основан на функциях генератора и обещаниях.

А на чем полагаются обещания? Правильно! Об обратных вызовах.

Это обстоятельство означает, что async-await является более высокой абстракцией и дает нам лучший способ инкапсулировать старые концепции. Но сохраняется ли та же проблема?

Закон дырявых абстракций тянет нас вниз. - Джоэл Спольски

Async-Await можно использовать только с функциями, которые уже полагаются на обещания.

Если у вас есть методы, которых нет, преобразуйте их для использования async-await.

Используйте технику обертывания, чтобы внедрить async в свои проекты. Оберните обещание вокруг функции, основанной на обратном вызове.

Вот пример использования Node.js readFile():

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

Привет, Арнольд! Вы же не можете серьезно относиться к тому, что теперь мы должны обернуть все наши функции обещаниями, верно?

Node.Js обещает прийти на помощь

Если вы работаете в среде на основе Node.js, вы можете закрепить это.

Существует рекомендация, согласно которой обратный вызов является последним параметром функции.

Тогда возвращаемая ошибка является первым параметром этой функции. Когда ваш код соответствует этим рекомендациям, вы можете использовать служебную функцию Node.js promisify.

Привет, Арнольд! Но это та же процедура, немного ускоренная, и только если мы следовали этому руководству в прошлом.

Асинхронное ожидание в Node.Js 8.0

В Node 8.0 появилась утилита для объединения promisify с использованием async-await ключевых слов.

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

Посмотрите на этот код, он читается как синхронный?

Да, но исполнение не синхронное.

Функция после await разделяется на подпрограмму. Технически это функция генератора, и во время ожидания асинхронный код может продолжать выполняться.

Чтобы использовать await, отметьте саму функцию ключевым словом async. Интересно, что вызова функции processFile тоже можно дождаться. Пока вызывающий метод также помечен как асинхронный.

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

Помните ту часть, где я упоминал пирамиду гибели?

Даже с использованием Async-Await мы можем построить пирамиду судьбы.

Новая техника, старые проблемы.

Привет, Арнольд! Возникает вопрос: каким должен быть первый порядок в этой цепочке? Разве тогда не должна быть асинхронной и основная функция / точка входа?

Начальная точка программы

Технически да, но этот синхронный. Первая помощь может представлять собой самовызывающуюся асинхронную функцию:

Дополнительные возможности:

  • тогда и поймай
  • ожидание верхнего уровня в модуле

Этот StackOverflow-answer объясняет другие способы вызова асинхронного режима первого порядка.

Бонус: Async можно использовать с лямбда-функциями

Async также можно использовать с лямбда-выражениями, как и в примере с try-catch (03_AsyncAwait.js). Это невозможно с чистыми обещаниями или обратными вызовами.

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

Специально для петель async-await оказался очень полезным. Это делает ваш цикл понятным без асинхронного мышления, хотя это так.

Вы когда-нибудь пытались создать цикл с использованием чистого обратного вызова или кода, основанного на обещаниях? Тогда вы понимаете, о чем я говорю.

Спасает ли асинхронное ключевое слово?

Да и нет.

Возможно, async-await не решает фундаментальных проблем разработки программного обеспечения. JavaScript не развивался и набирался навыков. Кроме того, эти два ключевых слова не решают новых технических проблем.

И эти утверждения верны. Но повышение читабельности и, следовательно, уменьшение затрат времени на понимание кода - огромное преимущество async-await.

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

Я бы сказал, что async-await сделал свою позицию более, чем просто ясной, и много использует JavaScript.

Если вам нужен более качественный обработанный программный контент, посетите мои приключения на Udemy.

Узнать больше от меня







использованная литература

Пирамида Судьбы - https://levelup.gitconnected.com/escape-the-pyramid-of-doom-c58edd326225
Ад обратного вызова - http : //callbackhell.com/
Async.js - https://caolan.github.io/async/v3/
Джоэл о программном обеспечении - https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/
Официальная документация API Node.Js util.Promisify - https://nodejs.org/dist/latest-v8.x/docs/api/util.html
Асинхронная запись из основного - https: // stackoverflow.com/questions/46515764/how-can-i-use-async-await-at-the-top-level