Promisifying Callback-based Asynchronous Functions

JavaScriptJavaScriptBeginner
Practice Now

Introduction

In this project, you will learn how to promisify a callback-based asynchronous function in JavaScript. Specifically, you will convert the callback-based readFile function from the fs module in Node.js into a Promise-based version.

🎯 Tasks

In this project, you will learn:

  • How to identify the conditions for promisifying a function
  • How to implement a promisefy function to wrap a callback-based function and return a Promise
  • How to use the Promise-based version of the readFile function to read a file asynchronously

🏆 Achievements

After completing this project, you will be able to:

  • Understand the benefits of using Promises over callback-based asynchronous programming
  • Implement a generic promisefy function to convert callback-based functions into Promise-based ones
  • Utilize Promise-based asynchronous functions in your own projects to improve code readability and error handling

Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL javascript(("`JavaScript`")) -.-> javascript/AdvancedConceptsGroup(["`Advanced Concepts`"]) javascript/AdvancedConceptsGroup -.-> javascript/es6("`ES6 Features`") subgraph Lab Skills javascript/es6 -.-> lab-301446{{"`Promisifying Callback-based Asynchronous Functions`"}} end

Promisify the readFile Function

In this step, you will learn how to promisify the readFile function from the fs module in Node.js. Follow the steps below to complete this step:

  1. Open the index.js file in your code editor.
  2. Require the necessary modules at the top of the file:
const fs = require("fs");
const path = require("path");
  1. Define the file path for the test-promisefy.json file:
const textPath = path.join(__dirname, "/test-promisefy.json");
  1. Implement the promisefy function:
const promisefy = (fn) => {
  return (textPath, type) => {
    return new Promise((resolve, reject) => {
      fn(textPath, type, (err, contrast) => {
        if (err) {
          reject(err);
        } else {
          resolve(contrast);
        }
      });
    });
  };
};

The promisefy function takes a callback-based function fn as an argument and returns a new function that returns a Promise. The returned function calls the original fn function, and resolves the Promise with the result or rejects it with the error.

  1. Use the promisefy function to create a Promise-based version of the readFile function:
const readFileSync = promisefy(fs.readFile);

Now, you can use the readFileSync function to read the test-promisefy.json file asynchronously using Promises.

Read the File Using the Promise-Based readFile Function

In this step, you will learn how to use the Promise-based readFileSync function to read the test-promisefy.json file.

  1. Add the following code to the index.js file:
fs.readFile(textPath, "utf8", (err, contrast) => {
  const readFileSync = promisefy(fs.readFile);

  readFileSync(textPath, "utf8")
    .then((res) => {
      console.log(res === contrast); // The result here is expected: true, i.e. the promise returns the same content as the previous read.
    })
    .catch((err) => {});
});

This code calls the readFileSync function with the file path and encoding, and then handles the Promise resolution and rejection using the then and catch methods.

  1. Now, your index.js file should look like this:
const fs = require("fs");
const path = require("path");
const textPath = path.join(__dirname, "/test-promisefy.json");

fs.readFile(textPath, "utf8", (err, contrast) => {
  const readFileSync = promisefy(fs.readFile);

  readFileSync(textPath, "utf8")
    .then((res) => {
      console.log(res === contrast); // The result here is expected: true, i.e. the promise returns the same content as the previous read.
    })
    .catch((err) => {});
});

const promisefy = (fn) => {
  return (textPath, type) => {
    return new Promise((resolve, reject) => {
      fn(textPath, type, (err, contrast) => {
        if (err) {
          reject(err);
        } else {
          resolve(contrast);
        }
      });
    });
  };
};

module.exports = promisefy;
  1. Run the index.js file in the terminal:
node index

You should see the output true, which means that the Promise-based readFile function returned the same content as the original callback-based readFile function.

Congratulations! You have successfully promisified the readFile function and used the Promise-based version to read a file.

Summary

Congratulations! You have completed this project. You can practice more labs in LabEx to improve your skills.

Other JavaScript Tutorials you may like