Node.js read file using async/await

There are many ways to achieve that.

Most of them is explained in this link


I'll write simple one:

1) using util.promisify to convert callback method to promise:

const fs = require('fs');
const util = require('util');
const readFile = (fileName) => util.promisify(fs.readFile)(fileName, 'utf8');

(async () => {
  try {
    const files = ['file1.txt', 'file2.txt', 'file3.txt'];
    for (const file of files) {
      console.log(
        await readFile(file)
      );
    }
  }
  catch (error) {
    console.error(error);
  }
})();

2) *Sync methods. Since Your code is not dealing with concurrency You can use *Sync methods:

const fs = require('fs');

try {
  const files = ['file1.txt', 'file2.txt', 'file3.txt'];
  for (const file of files) {
    console.log(
      fs.readFileSync(file, 'utf8')
    );
  }
}
catch (error) {
  console.error(error);
}


BTW. Here is Your fixed code:

var fs = require('fs');

function readFile(fileName) {
  return new Promise((resolve, reject) => {
    fs.readFile(fileName, 'utf8', function (error, data) {
      if (error) return reject(error);

      console.log(fileName)
      console.log(data)

      resolve();
    })
  });
}

async function run() {
  await readFile('file1.txt');
  await readFile('file2.txt');
  await readFile('file3.txt');
}

run();

since You're calling readFile and resolve at same async sequence it's being called at same time which is reason of race condition.

You've to wait for callback handling and then resolve it (inside callback scope).


There are a couple options with native node functionality

A) With the fs.promises API

You can use destructuring assignment on import to alias fs.promises as just fs

const { promises: fs } = require("fs");

(async () => {
    try {
        let file1 = await fs.readFile("file1.txt", "utf-8");
        let file2 = await fs.readFile("file2.txt", "utf-8");

    } catch (e) {
        console.log("e", e);
    }
})()

B) With util.promisify API

const fsSync = require("fs");
const {promisify} = require("util")

const fs = {
  readdir: promisify(fsSync.readdir),
  readFile: promisify(fsSync.readFile),
  // etc
};

(async () => {
    try {
        let file1 = await fs.readFile("file1.txt", "utf-8");
        let file2 = await fs.readFile("file2.txt", "utf-8");

    } catch (e) {
        console.log("e", e);
    }
})()

Further Reading

  • How to read file with async/await properly?
  • Using filesystem in node.js with async / await