Дорожная карта карьеры фронтенд-разработчика на 2023 — подробное пошаговое руководство

год назад·8 мин. на чтение

Если вы хотите входить в 5% высокооплачиваемых Frontend-разработчиков, независимо от того, являетесь ли вы абсолютным новичком или middle разработчиком - тогда этот роадмап для вас.

Это руководство будет для вас полезно, если вы хотите:
  • Начать свою карьеру в качестве фронтенд-разработчика и сразу же выйти на рынок.
  • Развить свои навыки и карьеру, чтобы получить более высокооплачиваемую работу.
  • Найти удаленную работу мечты.

Не бойтесь учиться — будьте последовательны

Не бойтесь увидеть длинный список учебных материалов. Просто идите маленькими шажками, и вы скоро доберетесь поставленных целей. Если вам нравится процесс, то все, что вам нужно делать, это оставаться последовательным. Без лишних слов вот пошаговая карта развития:
  1. Основы computer science
  2. HTML & CSS
  3. CSS фреймворки (Sass, Tailwind)
  4. JavaScript
  5. React.js
  6. Next.js
  7. TypeScript
  8. Jest/React-testing-library
  9. Git
  10. REST API
  11. GraphQL
  12. Принципы дизайна и основы UI/UX

Основы computer science

Как фронтенд-инженер, вы должны хорошо разбираться в информатике и основах программирования. Сюда входят структуры данных, алгоритмы и принципы проектирования программного обеспечения. Вы также должны быть знакомы с языками программирования и инструментами, обычно используемыми во фронтенд-разработке. Наличие прочной основы в области computer science поможет вам создавать более качественные веб-приложения и улучшать свои навыки решения проблем.

HTML и CSS

Столпами фронтенд разработки по-прежнему являются HTML и CSS, первый позволяет вам определить скелет веб-страницы, а последний поможет вам придать этому скелету форму. Что касается CSS, убедитесь, что вы хорошо понимаете следующие концепции:
  • Селекторы: понимание того, как выбирать определенные элементы HTML, чтобы применять к ним стили.
  • Блочная модель: понимание макета HTML-элементов, включая то, как ширина, высота, отступы, границы и поля вычисляются и взаимодействуют друг с другом.
  • Отображение и позиционирование: понимание того, как управлять тем, как элементы отображаются на экране (например, в виде блока (block) или инлайн (inline) элемента) и позиционируются по отношению к другим элементам (например, статические (static), абсолютные (absolute), относительные (relative), фиксированные (fixed)).
  • Переходы (transitions) и анимация (animations): понимание того, как создавать простые анимации и переходы с помощью CSS без использования JavaScript.
  • Препроцессоры CSS: понимание того, как использовать препроцессоры CSS, такие как Sass и Stylus, для написания более удобного в сопровождении модульного CSS.
  • Совместимость с браузерами: Понимание совместимости браузеров и способов написания CSS, который будет одинаково работать в разных браузерах и на разных устройствах.
  • Отзывчивый (responsive) дизайн: понимание того, как создавать дизайны, которые адаптируются к разным размерам экрана и устройствам, используя
  • Медиа-запросы (@media): CSS медиа запросы используются для изменения стиля вашего сайта в зависимости от размера экрана или используемого устройства. Медиа запросы в основном используются при разработке стилей для разных размеров экрана, что позволяет применять определенные правила только к определенным размерам экрана.
  • Контейнерные запросы (@container): эти запросы помогают изменять стили элементы в зависимости от размера содержащего их элемента, а не окна браузера.
  • Flexbox и Grid: Понимание основ flexbox и grid, которые представляют собой макеты CSS, позволяющие создавать сложные адаптивные дизайны с минимальным количеством кода.

CSS фреймворки

Вот несколько популярных фреймворков CSS, которые вы можете изучить в 2023 году. Освойте хотя бы один из них.
  • TailwindCSS: CSS фреймворк, ориентированный на утилиты. Tailwind предоставляет набор CSS классов, которые можно использовать для быстрого применения общих стилей к HTML элементам. Это способствует написанию минимального и семантического CSS. Легкий, отзывчивый и современный CSS-фреймворк. Он разработан, чтобы стать отправной точкой для любого типа проекта, требующего гибкой системы сетки и базового стиля.
  • Material-UI: это популярный CSS фреймворк, которая реализует рекомендации по Material UI дизайну, разработанные Google. Он включает в себя широкий спектр предварительно разработанных пользовательских компонентов.
  • Storybook: это не совсем CSS фреймворк. Это инструмент для изолированной разработки UI компонентов для React и многих других библиотек и фреймворков.
  • Bootstrap: один из самых популярных CSS фреймворков. Bootstrap представляет собой комплексный набор инструментов, который включает в себя предварительно разработанные компоненты, адаптивную сетку и поддержку CSS препроцессоров.
  • Sass: это препроцессором CSS, который упрощает и ускоряет написание CSS-кода. На нашем сайте есть подробное руководство по Sass. Рекомендуем ознакомиться.

JavaScript

Невозможно говорить о фронтенде, не упомянув JavaScript. Это язык фронтенда по определению. Вот самые важные понятия, которые вам нужно усвоить:
  • Переменные (var, let, const)
  • Примитивные типы данных и объекты
  • Операторы сравнения JavaScript
  • Операторы if/else и switch
  • Функции и стрелочные функции
  • Объекты
  • Массивы
  • Шаблонные литералы
  • Области видимости — глобальная, блочная, функциональная
Также получайте ежедневные советы по фронтенд-разработке в бесплатном телеграм-канале.

React.js

React.js — это JavaScript библиотека для создания пользовательских интерфейсов, которая широко используется в веб-разработке. Вот несколько причин, по которым вы можете захотеть изучить React.js:
  • Популярность: React является одной из самых популярных JavaScript библиотек для создания пользовательских интерфейсов и имеет большое и активное сообщество, а это означает, что существует множество доступных ресурсов, которые помогут вам учиться. На нашем сайте вы можете найти много материалов по ReactJS.
  • Переиспользуемые компоненты. Одной из ключевых особенностей React является то, что он позволяет создавать пользовательский интерфейс с помощью переиспользуемых компонентов, что упрощает создание и поддержку больших и сложных приложений.
  • Виртуальный DOM: React использует виртуальный DOM, который может оптимизировать производительность вашего приложения за счет уменьшения количества обновлений реального DOM. Это может сделать ваше приложение более отзывчивым.
  • Поддержка рендеринга на стороне сервера: React позволяет вам рендерить приложение на стороне сервера, что может повысить производительность приложения, особенно для пользователей с медленным подключением к Интернету.
  • Большая экосистема: React имеет большую и растущую экосистему, включающую множество популярных библиотек, фреймворков и инструментов, таких как React Router, Redux, Webpack и т. д.
  • Широкое распространение: React широко используется компаниями и организациями всех размеров, его используют Instagram, Airbnb, Netflix, Uber и т. д.
  • Легче учиться: React следует более простому и интуитивно понятному подходу к созданию пользовательского интерфейса, что упрощает его изучение и понимание.
  • Большое количество вакансий: поскольку React используется большим количеством компаний, для React разработчика существует множество вакансий.
Таким образом, React.js — это мощная, гибкая и популярная библиотека для создания пользовательских интерфейсов, и знание React - это важный навык в современном мире веб-разработки. В полном руководстве по Реакт вы можете найти пошаговый гайд по разработке на ReactJS.

Next.js

Next.js — это фреймворк, созданный на основе React.js, который упрощает создание приложений React с рендерингом на стороне сервера (SSR). Такие приложения включают автоматическое разделением кода и оптимизированы для SEO. Вот несколько причин, по которым вам может понадобиться изучить Next.js.
  • Рендеринг на стороне сервера (Server-side rendering, SSR): Next.js упрощает создание приложений React, которые рендерятся на сервере. Это повышает производительность вашего приложения и сделать его более оптимизированным для SEO.
  • Автоматическое разделение кода: Next.js автоматически разбивает ваш код на более мелкие фрагменты, так что браузер загружает только тот JavaScript, который требуется для отображения текущей страницы, что может повысить производительность вашего приложения.
  • Простота разработки и развертывания: Next.js обеспечивает простой и последовательный процесс разработки и имеет встроенную поддержку таких функций, как горячая перезагрузка кода и автоматическая транспиляция. Он также обеспечивает простое и согласованное развертывание с поддержкой широкого спектра вариантов хостинга, включая статический хостинг и бессерверные функции (serverless).
  • Генерация статического сайта (Static site generation): Next.js позволяет создавать статические HTML-страницы во время сборки, что может быть полезно для создания статических версий ваших страниц для повышения производительности или для обеспечения доступности вашего приложения в offline режиме.
  • Plug-and-play: Next.js имеет большую экосистему надстроек, плагинов и пакетов, которые вы можете использовать для добавления функциональности в свое приложение. Вы можете использовать такой пакет, как NextAuth, чтобы добавить аутентификацию, или пакет, такой как NextI18next, чтобы добавить интернационализацию.
  • Система роутинга: Next.js предоставляет мощную систему роутинга, которая позволяет вам определять маршруты и обрабатывать загрузку и рендеринг данных для конкретных маршрутов.
  • Сообщество: у Next.js большое и активное сообщество, а это значит, что есть много ресурсов, которые помогут вам учиться

TypeScript

TypeScript — это надмножество JavaScript с типами, который компилируется в простой JavaScript. Он предоставляет множество функций, которые помогут вам писать более надежный, удобный в сопровождении и масштабируемый код. Вот несколько причин, по которым вы можете захотеть изучить TypeScript:
  • Строгая типизация: TypeScript предоставляет строгую типизацию, которая может помочь вам обнаружить ошибки типизации во время компиляции, а не во время выполнения. Это может сделать ваш код менее подверженным ошибкам и более простым в обслуживании.
  • Улучшенный IntelliSense: система типов TypeScript обеспечивает улучшенный IntelliSense, подсказки кода и проверку ошибок в инструментах разработки, таких как Visual Studio Code, которые могут помочь вам писать код более эффективно и сократить время, затрачиваемое на отладку.
  • Улучшенная документация. Включая аннотации типов в свой код, вы можете создавать более самодокументируемый код, облегчая понимание и работу с ним для других.
  • Совместимость: TypeScript разработан как надмножество JavaScript, что означает, что вы можете использовать любой допустимый код JavaScript в TypeScript. Это упрощает постепенное внедрение в существующую кодовую базу JavaScript.
  • Большое сообщество: TypeScript имеет большое и активное сообщество, а это означает, что существует множество ресурсов, которые помогут вам учиться.
  • Повышенная масштабируемость: функции и система типов TypeScript позволяют писать более удобный и масштабируемый код, поскольку это упрощает организацию и анализ кода, что делает его особенно полезным для большой кодовой базы и долгосрочных проектов.
  • Используется крупными компаниями: TypeScript используется многими крупными компаниями и проектами с открытым исходным кодом, включая Asana, Asos, Airbnb, Microsoft, Asp.net, Angular и т. д.
На нашем сайте есть подробное руководство по TypeScript.

Тестирование с помощью Jest/react-testing-library

Jest — это популярный JavaScript фреймворк для тестирования, который широко используется для тестирования приложений JavaScript и React. Вот несколько причин, почему вы можете захотеть изучить Jest:
  • Простота в использовании: Jest разработан так, чтобы его было легко использовать, и он имеет простой и интуитивно понятный API, который позволяет легко приступить к тестированию JavaScript кода.
  • Snapshot тестирование: Jest имеет встроенную поддержку snapshot тестирования, что позволяет вам автоматически делать “снимок” выходных данных вашего компонента и сравнивать его с предыдущим “снимком”. Это может помочь вам обнаружить неожиданные изменения в ваших компонентах и упростить обновление ваших тестов.
  • Интегрированная библиотека функций для проверок: Jest включает в себя функции для проверок, что избавляет от необходимости устанавливать дополнительную библиотеку, такую как chai или expect.
  • Мощные возможности для моков: Jest предоставляет мощные возможности мокирования, которые позволяют вам легко имитировать и делать заглушки для функций, модулей и других объектов в вашем коде.
  • Скорость и производительность: Jest запускает ваши тесты параллельно, что может значительно ускорить работу вашего набора тестов. Jest также имеет быстрый и эффективный механизм тестирования, который может быстро запускать тесты в памяти, поэтому вам не нужно запускать браузер или Node.js процесс.
  • Создан для React: Jest создан с учетом React и имеет набор функций, специально разработанных для хорошей работы с React и React Native. Сюда входят такие функции, как автоматическое обнаружение и мокирование зависимостей компонента, возможность тестирования взаимодействия компонентов и поддержка JSX.
  • Большое сообщество: у Jest большое и активное сообщество, а это значит, что есть много ресурсов, которые помогут вам учиться.

Git

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

REST API

Одним из самых популярных типов API является REST или, как их иногда называют, RESTful API. У REST или RESTful API есть много преимуществ — они предназначены для использования особенностей существующих протоколов. Хотя REST может использоваться практически по любому протоколу, при использовании для web API он обычно использует преимущества HTTP. Это означает, что разработчикам не нужно устанавливать дополнительное программное обеспечение или библиотеки при создании REST API. Одно из ключевых преимуществ REST API заключается в том, что он обеспечивает большую гибкость. Эта гибкость позволяет разработчикам создавать API, который отвечает вашим потребностям, а также удовлетворяет потребности самых разных клиентов.

GraphQL

GraphQL — это язык запросов и серверная среда выполнения для API, которая отдает пользователям только те данные, которые они запрашивают, и не более. GraphQL разработан, чтобы сделать API быстрыми, гибкими и удобными для разработчиков. Его даже можно развернуть в интегрированной среде разработки (IDE), известной как GraphiQL. В качестве альтернативы REST GraphQL позволяет разработчикам создавать запросы, которые извлекают данные из нескольких источников данных за один вызов API. Кроме того, GraphQL дает специалистам по обслуживанию API возможность добавлять или удалять поля, не затрагивая существующие запросы. Разработчики могут создавать API любыми методами, которые они предпочитают, а спецификация GraphQL гарантирует, что они будут работать предсказуемо для клиентов. Вот полное руководство по GraphQL для быстрого старта.

Принципы дизайна и основы UI/UX

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

Полное руководство по асинхронному JavaScript

год назад·7 мин. на чтение

На пути к тому, чтобы стать разработчиком JavaScript, вы, вероятно, столкнетесь с функциями обратного вызова, промисами (promise) и async/await.

JavaScript по своей сути является синхронным или однопоточным языком. Это означает, что каждое действие выполняется одно за другим, и каждое действие зависит от выполнения предыдущего. Думайте об этом как о машинах, ожидающих на светофоре. Каждая машина должна ждать, пока заведется предыдущая.
const firstCar = 'first car';
const secondCar = 'second car';

console.log('Start ' + firstCar);
console.log('Start ' + secondCar);
Результат выполнения кода.
Start first car
Start second car
Но что произойдет, если первая машина сломается? Должны ли все остальные машины ждать? У кого есть на это время?
const firstCar = 'broken';
const secondCar = 'second car';

if (firstCar === "broken") {
  throw Error("The first car is broken. Everybody stop.");
}

console.log('Start ' + firstCar);
console.log('Start ' + secondCar);
Результат выполнения кода.
Error: The first car is broken. Everybody stop.
Не лучше ли было бы, чтобы каждая машина не зависела от предыдущей? Почему нас должно волновать, если какая-то машина сломана? Если моя машина работает, почему я должен ждать, пока кто-нибудь заведет ее машину? Разве я не могу просто объехать ее? Это и позволяет нам делать асинхронный JavaScript. Он создает для нас еще одну «полосу». Асинхронность означает, что если JavaScript должен дождаться завершения операции, он выполнит остальную часть кода во время ожидания. Мы можем переместить наши действия с основной линии и выполнять их в своем собственном темпе, позволяя им заниматься своими делами. И как мы этого добиваемся? Используя обратные вызовы, промисы и async/await.

Функции обратного вызова (callback)

Обратные вызовы — это функции, вложенные в другую функцию в качестве аргумента. Их можно использовать как часть синхронного или асинхронного кода. Синхронный обратный вызов выполняется во время выполнения функции высшего порядка, которая использует обратный вызов.
function startFirst(car, callback) {
  console.log("Start " + car);
  callback();
}

// функция обратного вызова
function startSecond() {
  console.log("Start second car");
}

// передача функции как аргумент
startFirst("first car", startSecond);
Результат выполнения кода.
Start first car
Start second car
Мы также можем сделать обратные вызовы частью асинхронного JavaScript. Асинхронный обратный вызов выполняется после выполнения функции высшего порядка, которая использует колбэк. Если наша машина сломается, мы отвезем ее к механику, после чего снова сможем ею пользоваться. Сначала нам нужно подождать некоторое время, чтобы починить машину. Смоделируем ожидание с помощью setTimeout, а затем мы сможем наслаждаться вождением нашей только что починенной машины.
function fixMyCar(car) {
  setTimeout(() => {
    console.log(`Fixing your ${car}.`);
  }, 1000);
}

function driveMyCar(car) {
  console.log(`Driving my new ${car}.`);
}

let myCar = "BMW x5";

fixMyCar(myCar);
driveMyCar(myCar);
Результат выполнения кода.
Driving my new BMW x5.
Fixing your BMW x5.
JavaScript сначала выполнил синхронный код (в нашем случае вызов функции driveMyCar()), а затем через 1000 миллисекунд записал результат fixMyCar(). Но как мы можем водить машину, если она еще не починена? Мы должны передать функцию driveMyCar() в качестве колбэка функции fixMyCar(). Таким образом, функция driveMyCar() не будет выполняться до тех пор, пока автомобиль не будет отремонтирован.
function fixMyCar(car, callback) {
  setTimeout(() => {
    console.log(`Fixing your ${car}.`);
    callback(car);
  }, 1000);
}

function driveMyCar(car) {
  console.log(`Driving my new ${car}.`);
}

let myCar = "BMW x5";

fixMyCar(myCar, driveMyCar);
Результат выполнения кода.
Fixing your BMW x5.
Driving my new BMW x5.
Что ж, отлично, мы починили нашу машину и теперь можем на ней ездить. Но что, если нашу машину нельзя починить? Как мы будем обрабатывать ошибки? А как насчет ремонта нескольких автомобилей каждый день? Давайте посмотрим на это в действии.
function fixMyCar(car, success, failure) {
  setTimeout(() => {
    car ? success(car) : failure(car);
  }, 1000);
}

const car1 = "BMW x5";
const car2 = "Toyota RAV4";
const car3 = "Honda Civic";

fixMyCar(
  car1,
  function (car1) {
    console.log(`Fixed your ${car1}.`);
    fixMyCar(
      car2,
      function (car2) {
        console.log(`Fixed your ${car2}.`);
        fixMyCar(
          car3,
          function (car3) {
            console.log(`Fixed your ${car3}.`);
          },
          function (car3) {
            console.log(`Your ${car3} car can not be fixed.`);
          }
        );
      },
      function (car2) {
        console.log(`Your ${car2} car can not be fixed.`);
      }
    );
  },
  function (car1) {
    console.log(`Your ${car1} car can not be fixed.`);
  }
);
Результат выполнения кода.
Fixed your BMW x5.
Fixed your Toyota RAV4.
Fixed your Honda Civic.
У вас кружится голова, пытаясь понять это? Не волнуйтесь, вы не одиноки. Есть причина, по которой это явление называется callback hell. Кроме того, обратите внимание, что если одна из машин разбита, то есть ее не получается определить, другие машины даже не получат шанса на ремонт.
function fixMyCar(car, success, failure) {
  setTimeout(() => {
    car ? success(car) : failure(car);
  }, 1000);
}

const car1 = "BMW x5";
const car2 = undefined;
const car3 = "Honda Civic";

fixMyCar(
  car1,
  function (car1) {
    console.log(`Fixing your ${car1}.`);
    fixMyCar(
      car2,
      function (car2) {
        console.log(`Fixing your ${car2}.`);
        fixMyCar(
          car3,
          function (car3) {
            console.log(`Fixing your ${car3}.`);
          },
          function (car3) {
            console.log(`Your ${car3} car can not be fixed.`);
          }
        );
      },
      function (car2) {
        console.log(`Your ${car2} car can not be fixed.`);
      }
    );
  },
  function (car1) {
    console.log(`Your ${car1} car can not be fixed.`);
  }
);
Результат выполнения кода.
Fixing your BMWx5.
Your undefined car can not be fixed.

Промисы (Promise)

Promise — это объект, который можно использовать для получения результата асинхронной операции, когда этот результат недоступен прямо сейчас. Поскольку код JavaScript выполняется неблокирующим образом, промисы становятся необходимыми, когда нам нужно дождаться какой-либо асинхронной операции, не задерживая выполнение остального кода. Промисы JavaScript — это объект, который может находиться в одном из трех состояний.
  • Pending (в ожидании) - обещание еще не выполнено (ваша машина у механика)
  • Fulfilled (выполнено) - запрос выполнен успешно (автомобиль отремонтирован)
  • Rejected (отклонено) - запрос не выполнен (автомобиль не может быть починен)
Чтобы создать промис в JavaScript, используйте ключевое слово new и внутри конструктора передайте функцию-исполнитель. Затем эта функция отвечает за разрешение или отклонение промиса. Давайте представим следующий сценарий. Если нашу машину починят, то мы сможем отправиться в отпуск. Там мы можем осмотреть достопримечательности, затем мы можем сделать несколько снимков, опубликовать их в социальных сетях. Но если машину нельзя починить, то придется остаться дома. Давайте напишем наши шаги.
  • Механик обещает, что починит нашу машину
  • Починить машину — значит отправиться в отпуск.
  • Оказавшись там, мы можем отправиться на экскурсию
  • Сделаем несколько фотографий
  • После этого мы опубликуем их в социальных сетях
Используем setTimeout для имитации асинхронности.
const mechanicsPromise = new Promise(
  (resolve, reject) => {
    setTimeout(() => {
      const fixed = true;
      if (fixed) resolve("Car is fixed");
      else reject("Car can not be fixed");
    }, 2000);
});

console.log(mechanicsPromise);
Результат выполнения кода.
Promise { <pending> }

[[Prototype]]: Promise
[[PromiseState]]: "pending"
[[PromiseResult]]: undefined
Но почему PromiseResult - undefined? Разве ваш механик не говорил вам, что попытается починить вашу машину? Нет, ваш механик вас не обманывал. Что мы забыли сделать, так это обработать промис. И как мы это делаем? Используя методы .then() и .catch().
const mechanicsPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const fixed = true;
    if (fixed) resolve("Car is fixed");
    else reject("Car can not be fixed. Go home");
  }, 2000);
});

mechanicsPromise
  .then((message) => {
    console.log(`Success: ${message}`);
  })
  .catch((error) => {
    console.log(error);
  });
Результат выполнения кода.
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Success: Car is fixed
Как видно из блока кода выше, мы используем .then() для получения результата метода resolve() и .catch() для получения результата метода reject(). Наша машина починена, и теперь мы можем отправиться в отпуск и сделать все, что планировали. Метод .then() возвращает новое промис с результатом, преобразованным в значение. Мы можем вызвать метод .then() для возвращенного промиса следующим образом:
const mechanicsPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const fixed = true;
    if (fixed) resolve("Car is fixed");
    else reject("Car can not be fixed");
  }, 2000);
});

mechanicsPromise
  .then((message) => {
    console.log(`Success: ${message}`);
    message = "Go sight seeing";
    return message;
  })
  .then((message) => {
    console.log(message);
    message = "Take some pictures";
    return message;
  })
  .then((message) => {
    console.log(message);
    message = "Posting pictures on social media";
    console.log(message);
  })
  .catch((error) => {
    console.log(error);
  })
  .finally(() => {
    console.log("Go home");
  });
Результат выполнения кода.
Success: Car is fixed
Go sight seeing
Take some pictures
Posting pictures on social media
Go home
Как вы можете видеть, после каждого вызова метода .then() мы вызывали еще один .then() с сообщением от предыдущего .then(). Мы также добавили .catch() для обнаружения любых ошибок, которые могут возникнуть. Если мы поедем или не поедем в отпуск, нам обязательно придется вернуться домой. Это то, что делает .finally(), этот метод всегда выполняется независимо от того, выполнено ли обещание или отклонено. Другими словами, метод .finally() выполняется, когда обещание (promise) выполнено. Наш код выглядит немного лучше, чем когда мы использовали колбэки. Но мы можем сделать это еще лучше с помощью специального синтаксиса под названием async/await. Это позволяет нам работать с промисами более удобным способом.

async/await

async/await позволяет нам писать промисы, но код будет выглядеть синхронным, хотя на самом деле он асинхронный. Под капотом мы все еще используем Promise. async/await — это синтаксический сахар, а это означает, что хотя он и не добавляет к нашему коду никаких новых функций, его приятнее использовать.
const mechanicsPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const fixed = true;
    if (fixed) resolve("Car is fixed");
    else reject("Car can not be fixed");
  }, 2000);
});

async function doMyThing() {
  let message = await mechanicsPromise;
  console.log(`Success: ${message}`);

  message = "Go sight seeing";
  console.log(message);

  message = "Take some pictures";
  console.log(message);

  message = "Posting pictures on social media";
  console.log(message);
  console.log("Go home");
}

doMyThing()
Результат выполнения кода.
Success: Car is fixed
Go sight seeing
Take some pictures
Posting pictures on social media
Go home
Как видите, ключевое слово await заставляет функцию приостанавливать выполнение и ждать разрешенного промиса, прежде чем оно продолжится. Ключевое слово await можно использовать только внутри асинхронной функции. А что, если машина сломается? Как мне обрабатывать ошибки с этим новым синтаксисом? Мы можем использовать блок try/catch.
const mechanicsPromise = new Promise((resolve, reject) => {
  setTimeout(() => {
    const fixed = false;
    if (fixed) resolve("Car is fixed");
    else reject("Car can not be fixed");
  }, 2000);
});

async function doMyThing() {
  try {
    let message = await mechanicsPromise;
    console.log(`Success: ${message}`);

    message = "Go sight seeing";
    console.log(message);

    message = "Take some pictures";
    console.log(message);

    message = "Posting pictures on social media";
    console.log(message);
    console.log("Go home");
  } catch (error) {
    console.log(error);
  }
}

doMyThing();
Результат выполнения кода.
Your car can not be fixed
Используйте блок try/catch только в том случае, если вызов помечен как await. В противном случае исключение не будет поймано.