Зарегистрируйтесь для доступа к 15+ бесплатным курсам по программированию с тренажером

Возврат в асинхронном коде JS: Асинхронное программирование

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

import fs from 'fs';

const noop = () => {};
const content = fs.readFile('./myfile', 'utf-8', noop);
console.log(content); // undefined

И единственный способ получить результат — описать логику в колбеке. Тогда возникает вопрос: а что, если сделать return внутри колбека? К чему это приведёт?

import fs from 'fs';

const content = fs.readFile('./myfile', 'utf-8', (_error, data) => {
  // что-нибудь делаем
  return data;
});
console.log(content); // undefined

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

import fs from 'fs';

const content = fs.readFile('./myfile', 'utf-8', (_error, data) => {
  if (data === '') {
    return;
  }
  // делаем что-нибудь с данными
});
console.log(content); // undefined

Этот паттерн называется guard expression.

Всё то же самое распространяется и на асинхронные функции, которые мы пишем сами. Асинхронной является любая функция, внутри которой есть хоть одна асинхронная операция. Без исключения. Даже если помимо асинхронной операции, она выполняет и синхронные, например, производит манипуляции с текстом. В свою очередь, каждая асинхронная функция обязана принимать на вход колбек, так как это единственный способ упорядочивать события и отслеживать завершение.

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

import fs from 'fs';

const readFileWithTrim = (filepath, cb) => {
  fs.readFile(filepath, 'utf-8', (_error, data) => {
    // При вызове колбек-функции передаем null первым параметром
    // Поскольку обработку ошибок мы пока не рассматриваем
    cb(null, data.trim());
  })
}

readFileWithTrim('./myfile', (_error, data) => console.log(data));

Этот процесс рекурсивен по своей природе, любая функция, которая внутри работает с асинхронной функцией, становится асинхронной и начинает принимать на вход колбек. Почему так происходит? Почему нельзя просто выполнить асинхронную операцию внутри, никак не сообщая об этом наружу? Дело в том, что в такой ситуации вы не можете ни воспользоваться результатом работы асинхронной функции (ведь данные приходят в колбек в другом стеке вызовов), ни узнать о том, закончилась ли операция вообще и закончилась ли она успешно. Всё это рассмотрим в следующих уроках.


Аватары экспертов Хекслета

Остались вопросы? Задайте их в разделе «Обсуждение»

Вам ответят команда поддержки Хекслета или другие студенты.

Для полного доступа к курсу нужен базовый план

Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.

Получить доступ
1000
упражнений
2000+
часов теории
3200
тестов

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов
Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»

Наши выпускники работают в компаниях:

Логотип компании Альфа Банк
Логотип компании Aviasales
Логотип компании Yandex
Логотип компании Tinkoff
Рекомендуемые программы
профессия
от 6 300 ₽ в месяц
Разработка фронтенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 1 июня
профессия
от 6 300 ₽ в месяц
Разработка бэкенд-компонентов для веб-приложений
10 месяцев
с нуля
Старт 1 июня
профессия
от 10 080 ₽ в месяц
Разработка фронтенд- и бэкенд-компонентов для веб-приложений
16 месяцев
с нуля
Старт 1 июня
профессия
от 6 300 ₽ в месяц
новый
Автоматизированное тестирование веб-приложений на JavaScript
10 месяцев
с нуля
в разработке
дата определяется

Используйте Хекслет по-максимуму!

  • Задавайте вопросы по уроку
  • Проверяйте знания в квизах
  • Проходите практику прямо в браузере
  • Отслеживайте свой прогресс

Зарегистрируйтесь или войдите в свой аккаунт

Отправляя форму, вы принимаете «Соглашение об обработке персональных данных» и условия «Оферты», а также соглашаетесь с «Условиями использования»