Использование Async Await

Если вы знакомы с Promises JavaScript, то это следующая итерация этого — более краткая и гибкая. Async Await — это просто синтаксический сахар, построенный на основе Promises. Так с какой стати они намного лучше, если это действительно та же самая реализация под капотом? Ну, есть немало причин. Но сначала давайте посмотрим, как его использовать.

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

const requestData = () => {
  try {
    return apiGetData()
      .then(data => {
        return data
      })
      .catch(err => {
        // Handle error
        console.log(err)
      })
  } catch (err) {
    // Handle error
    console.log(err)
  }

а теперь давайте попробуем использовать async/await:

const requestData = async () => {
  try {
    return await apiGetData()
  } catch (err) {
    // Handle error
    console.log(err)
  }
}

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

Почему async/await лучше

1. Краткость

Использование паттерна async/await поможет сократить объем кода, вложенности и цепочки, которые вам приходилось делать ранее. Ниже приведен пример использования промисов.

const requestData = () =>
  apiGetData()
    .then(data => data)

requestData()

А вот как это выглядит с async/await:

const requestData = async () => await apiGetData()

requestData()

2. Обработка ошибок

С помощью async/await обработка ошибок становится намного более читабельной.

const requestData = () => {
  try {
    apiGetData()
      .then(data => {
        return data
      })
      .catch(err => {
        console.log(err)
      })
  } catch (err) {
    console.log(err)
  }

Используя приведенный ниже паттерн async/await, блок catch теперь будет обрабатывать любые ошибки синтаксического анализа.

const requestData = async () => {
  try {
    return await apiGetData()
  } catch (err) {
    console.log(err)
  }
}

4. Условные операторы

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

const requestData = () => {
  return apiGetData()
    .then(data => {
      if (data.needsMoreData) {
        return makeAnotherRequest(data)
          .then(extraData => {
            return extraData
          })
      } else {
        return data
      }
    })
}

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

Теперь давайте попробуем это снова с помощью async/await!

const requestData = async () => {
  const data = await apiGetData()
  if (data.needsMoreData) {
    const extraData = await makeAnotherRequest(data);
    return extraData
  } else {
    return data    
  }
}

Вот так. Async/await должен быть вашим выбором вместо промисов или обратных вызовов (callback). По мере роста проектов удобочитаемость и чистота становятся одними из наиболее важных факторов, которые со временем помогут вам сократить технический долг.