Register to get access to free programming courses with interactive exercises

Return in asynchronous code JS: Asynchronous programming

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 need to ask what happens if we make a return inside the callback. What will this lead to?

import fs from 'fs';

const content = fs.readFile('./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. This does not mean that the return instruction itself is useless in asynchronous code. On the contrary, it's often useful, but only as a way to interrupt code execution and not to 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 of this applies to asynchronous functions that we write ourselves, too. 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. In turn, every asynchronous function is obliged to 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. Remember right away that 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, i.e., 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 in nature, 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 just perform an asynchronous operation internally without returning it outside the function in any way? The point is that in this situation you can neither use the result of an asynchronous function (because the data comes to the callback function in a different call stack), nor can you know whether the operation has finished at all, let alone whether it was successful. We'll look at all of this in future lessons.


Hexlet Experts

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

From a novice to a developer. Get a job or your money back!

Frontend Developer icon
Profession
beginner
Development of front-end components for web applications
start anytime 10 months

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.