Register to get access to free programming courses with interactive exercises

Return in asynchronous code JS: Asynchronous programming

Let's spend a bit more time on the returning of values from asynchronous functions.

In the last lesson, we learned that asynchronous functions never return the result of an asynchronous operation:

import fs from 'fs';

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

And the only way to get a result is to describe the logic in the callback. Then we should ask what happens if we make a return inside the callback. What will this lead to:

import fs from 'fs';

const content = fs.rea dFile('./myfile', 'utf-8', (_error, data) => {
  // doing something
  return data;
});
console.log(content); // undefined

As a result, nothing changes because this return isn't used by anything. It does not mean that the return instruction is useless in asynchronous code.

On the contrary, it's helpful as a way to interrupt code execution and not return the result:

import fs from 'fs';

const content = fs.readFile('./myfile', 'utf-8', (_error, data) => {
  if (data === '') {
    return;
  }
  // doing something with the data
});
console.log(content); // undefined

This pattern is called guard expression.

All the information above applies to asynchronous functions which we wrote on our own.

An asynchronous function is any function that has at least one asynchronous operation inside it. Without exception. Even if in addition to the asynchronous operation, it also performs a synchronous operation, for example, text modification. So, every asynchronous function must take a callback as its only way of ordering events and tracking completion.

Let's write an asynchronous wrapper function to read the file, which, besides the reading itself, does a little cleaning by removing leading and trailing spaces from the content.

Since our function is asynchronous, it must take a callback function as an input, and that function will be called at the end of the operation.

This function should have the generally accepted signature, with the first parameter as an error and the second as the data itself. Our asynchronous function cannot return data using return:

import fs from 'fs';

const readFileWithTrim = (filepath, cb) => {
  fs.readFile(filepath, 'utf-8', (_error, data) => {
    // Error handling hasn't been considered yet
    // Pass null as the first parameter when calling a callback function
    cb(null, data.trim());
  })
}

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

This process is recursive, so any function that internally works with an asynchronous function becomes asynchronous and starts taking a callback function as the input.

Why does this happen? Why can't you perform an asynchronous operation internally without returning it outside the function in any way? In this case, you can't:

  • Use the result of an asynchronous function because the data comes to the callback function in a different call stack
  • Find out whether the operation has finished, whether it was successful

We'll look at all of this in future lessons.


Are there any more questions? Ask them in the Discussion section.

The Hexlet support team or other students will answer you.

About Hexlet learning process

For full access to the course you need a professional subscription.

A professional subscription will give you full access to all Hexlet courses, projects and lifetime access to the theory of lessons learned. You can cancel your subscription at any time.

Get access
130
courses
1000
exercises
2000+
hours of theory
3200
tests

Sign up

Programming courses for beginners and experienced developers. Start training for free

  • 130 courses, 2000+ hours of theory
  • 1000 practical tasks in a browser
  • 360 000 students
By sending this form, you agree to our Personal Policy and Service Conditions

Our graduates work in companies:

<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.bookmate">Bookmate</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.healthsamurai">Healthsamurai</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.dualboot">Dualboot</span>
<span class="translation_missing" title="translation missing: en.web.courses.lessons.registration.abbyy">Abbyy</span>
Suggested learning programs
profession
Development of front-end components for web applications
10 months
from scratch
Start at any time

Use Hexlet to the fullest extent!

  • Ask questions about the lesson
  • Test your knowledge in quizzes
  • Practice in your browser
  • Track your progress

Sign up or sign in

By sending this form, you agree to our Personal Policy and Service Conditions
Toto Image

Ask questions if you want to discuss a theory or an exercise. Hexlet Support Team and experienced community members can help find answers and solve a problem.