How to return a value from an asynchronous callback function?
Post

How to return a value from an asynchronous callback function?

The example below is a function that returns a value using a callback function at stream completion. After reading the file, the end callback function returns a value. However, totalBytes is undefined. This is because return totalBytes is a value returned from the callback function of the end event.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const fs = require('fs');

function getTotalBytes(filePath) {
  let totalBytes = 0;

  const readStream = fs.createReadStream(filePath);

  readStream.on('data', (chunk) => {
    totalBytes += chunk.length;
  });

  readStream.on('end', () => {
    return totalBytes;
  });
}

const filePath = 'example.txt';
const totalBytes = getTotalBytes(filePath);
console.log(totalBytes); // Output: undefined 

Solution

If you modify it to return the Promise object, you can get the desired value.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const fs = require('fs');

function getTotalBytes(filePath) {
  return new Promise((resolve, reject) => {
    let totalBytes = 0;

    const readStream = fs.createReadStream(filePath);

    readStream.on('data', (chunk) => {
      totalBytes += chunk.length;
    });

    readStream.on('end', () => {
      resolve(totalBytes);
    });

    readStream.on('error', (error) => {
      reject(error);
    });
  });
}

const filePath = 'example.txt';
getTotalBytes(filePath)
  .then((totalBytes) => console.log(totalBytes))
  .catch((error) => console.error(error));